允许 C/C++ 中的有符号整数溢出
我希望有符号整数在变得太大时溢出。在不使用下一个最大数据类型(或者当我已经在 int128_t 时)的情况下,如何实现这一目标?
例如,使用 8 位整数 19*12 通常为 260,但我希望结果 1 11 10 01 00
第 9 位被截断,因此为 -27。
I want signed integers to overflow when they become too big. How do I achieve that without using the next biggest datatype (or when I am already at int128_t)?
For example using 8bit integers 19*12 is commonly 260, but I want the result 1 11 10 01 00
with the 9th bit cut off, thus -27.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
有符号溢出在 C 中未定义,这是真的。
一种解决方案如下:
上述解决方案在从
unsigned
到int
的最终转换中涉及实现定义的行为,但不调用未定义的行为。对于大多数编译平台的实现定义的选择,结果正是您期望的二进制补码结果。最后,针对众多平台之一的优化编译器,在这些平台上,实现定义的选择迫使编译器提供您期望的行为 会将上面的代码编译为明显的汇编指令。
或者,如果您使用 gcc,那么选项
-fwrapv
/-fno-strict-overflow
可能正是您想要的。它们为签名溢出环绕的标准提供了额外的保证。我不确定两者之间的区别。Signed overflow is undefined in C, and that's for real.
One solution follows:
The above solution involves implementation-defined behavior in the final conversion from
unsigned
toint
but do not invoke undefined behavior. With most compilation platforms' implementation-defined choices, the result is exactly the two's complement result that you expect.Finally, an optimizing compiler for one of the numerous platforms on which implementation-defined choices force the compiler to give you the behavior you expect will compile the above code to the obvious assembly instruction.
Alternately, if you are using gcc, then the options
-fwrapv
/-fno-strict-overflow
may be exactly what you want. They provide an additional guarantee with respect to the standard that signed overflows wrap around. I'm not sure about the difference between the two.只要您能够访问与您的
signed
类型宽度相同的unsigned
类型(即,多了一位值)。使用int64_t
进行演示:这不会产生任何有问题的中间结果。
It is possible to do this in a correct standard C manner, so long as you have access to an
unsigned
type that is of the same width as yoursigned
type (that is, has one more value bit). To demonstrate withint64_t
:This does not produce any problematic intermediate results.
根据 C 和 C++ 标准,有符号整数溢出是未定义的。如果没有考虑到特定的平台,就无法实现您想要的目标。
Signed integer overflow is undefined according to both C and C++ standards. There's no way to accomplish what you want without a specific platform in mind.
您可以围绕 int 创建一个客观包装器,但这会涉及大量开销代码。
You could create an objective wrapper around int, but that would involve quite a lot of overhead code.
假设采用二进制补码有符号整数运算(目前这是一个合理的假设),对于加法和减法,只需转换为无符号即可进行计算。对于乘法和除法,确保操作数为正,转换为无符号,计算并调整符号。
Assuming two's complement signed integer arithmetic (which is a reasonable assumption these days), for addition and subtraction, just cast to unsigned to do the calculation. For multiplication and division, ensure the operands are positive, cast to unsigned, calculate and adjust the signs.
听起来你想做无符号整数算术,然后将结果填充到有符号整数中:
应该给你你正在寻找的东西。如果没有,请告诉我们。
It sounds like you want to do unsinged integer arithmetic, then stuff the result into a signed integer:
should give you what you're looking for. Let us know if it doesn't.
使用更大的数据类型。使用GMP,您将拥有可能需要的所有空间。
Use bigger datatypes. With GMP you will have all the space you probably need.