我可以使用无符号右移来防止 C# 中的整数溢出吗?
我希望为alreValue1 和largeValue2 的所有可能值(这些值至少为1)为alwaysPositive 分配一个正数。
以下语句会导致缓冲区溢出:
int alwaysPositive = (largeValue1 + largeValue2) / 2;
我知道我可以通过减法和加法来防止它:
int alwaysPositive = largeValue1 + ((largeValue2 - largeValue1) / 2);
但在其他编程语言中,我可以使用无符号位移来实现这一点:
int alwaysPositive3 = (largeValue1 + largeValue2) >>> 1;
如何在 C# 中做到这一点?
下面的答案都可以解决问题。 可能有很多方法可以做到这一点,但它们(包括我的解决方案)都有一个共同点:它们看起来都很混乱。
I want alwaysPositive to be assigned a positive number with all possible values for lareValue1 and largeValue2 (these are at least 1).
The following statement causes a buffer overflow:
int alwaysPositive = (largeValue1 + largeValue2) / 2;
I know I can prevent it by substracting and adding:
int alwaysPositive = largeValue1 + ((largeValue2 - largeValue1) / 2);
But in other programming languages I can use an unsigned bitshift to do the trick:
int alwaysPositive3 = (largeValue1 + largeValue2) >>> 1;
How can I do this in C#?
The answers below all solve the problem. There are probably lots of ways to do this, but they all (including my solutions) have one thing in common: they all look obfuscated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
你可以这样做:
这是一种获得两个整数的平均值而不会溢出的有点麻烦的方法。
如果你愿意,你可以用位移位来代替除以二,但编译器无论如何都会为你做这件事。
You can do it this way:
That's a bit-twiddling way to get the average of two integers without overflow.
If you want you can replace the division by two with a bit-shift, but the compiler will do that for you anyways.
您可以使用单位:
You could use uints:
上述背后的想法是,如果在相加之前对结果进行预除,那么您将避免溢出,因为两个高位都将被重置。 然后,如果两者均为正值(向下舍入),则添加一些轻微的修正逻辑,将值增加 1。 如果您只关心其中一个是否为正(四舍五入),那么您可以将其更改为
The idea behind the above is that if you pre-divide the results before you add them, then you will avoid the overflow as both high-order bits will be unset. You then add some slight correction logic to increase the value by one if both were positive (round down). If you only care if either one was positive (round off) then you could change it to
unchecked((largeValue1 + largeValue2) >> 1)
是另一种选择。请参阅未选中的关键字的文档。
unchecked((largeValue1 + largeValue2) >> 1)
is another option.See the documentation for the unchecked keyword.
不是挑剔,但你的意思是“整数溢出”而不是“缓冲区溢出”。
我不懂 C#,所以可能还有另一种方法,但您可以通过屏蔽顶部位来模拟无符号移位: (x >> 1) & 0x80000000
Not to nitpick, but you mean "integer overflow" rather than "buffer overflow".
I don't know C#, so there may be another way, but you could mimic an unsigned shift by just masking off the top bit: (x >> 1) & 0x80000000