允许 C/C++ 中的有符号整数溢出

发布于 2024-10-03 19:47:50 字数 166 浏览 3 评论 0原文

希望有符号整数在变得太大时溢出。在不使用下一个最大数据类型(或者当我已经在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

山有枢 2024-10-10 19:47:50

有符号溢出在 C 中未定义,这是真的

一种解决方案如下:

signed_result = (unsigned int)one_argument + (unsigned int)other_argument;

上述解决方案在从 unsignedint 的最终转换中涉及实现定义的行为,但不调用未定义的行为。对于大多数编译平台的实现定义的选择,结果正是您期望的二进制补码结果。

最后,针对众多平台之一的优化编译器,在这些平台上,实现定义的选择迫使编译器提供您期望的行为 会将上面的代码编译为明显的汇编指令。

或者,如果您使用 gcc,那么选项 -fwrapv/-fno-strict-overflow 可能正是您想要的。它们为签名溢出环绕的标准提供了额外的保证。我不确定两者之间的区别。

Signed overflow is undefined in C, and that's for real.

One solution follows:

signed_result = (unsigned int)one_argument + (unsigned int)other_argument;

The above solution involves implementation-defined behavior in the final conversion from unsigned to int 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.

末が日狂欢 2024-10-10 19:47:50

只要您能够访问与您的 signed 类型宽度相同的 unsigned 类型(即,多了一位值)。使用 int64_t 进行演示:

int64_t mult_wrap_2scomp(int64_t a, int64_t b)
{
    uint64_t result = (uint64_t)a * (uint64_t)b;

    if (result > INT64_MAX)
        return (int64_t)(result - INT64_MAX - 1) - INT64_MAX - 1;
    else
        return (int64_t)result;
}

这不会产生任何有问题的中间结果。

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 your signed type (that is, has one more value bit). To demonstrate with int64_t:

int64_t mult_wrap_2scomp(int64_t a, int64_t b)
{
    uint64_t result = (uint64_t)a * (uint64_t)b;

    if (result > INT64_MAX)
        return (int64_t)(result - INT64_MAX - 1) - INT64_MAX - 1;
    else
        return (int64_t)result;
}

This does not produce any problematic intermediate results.

长途伴 2024-10-10 19:47:50

根据 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.

你的他你的她 2024-10-10 19:47:50

您可以围绕 int 创建一个客观包装器,但这会涉及大量开销代码。

You could create an objective wrapper around int, but that would involve quite a lot of overhead code.

你在我安 2024-10-10 19:47:50

假设采用二进制补码有符号整数运算(目前这是一个合理的假设),对于加法和减法,只需转换为无符号即可进行计算。对于乘法和除法,确保操作数为正,转换为无符号,计算并调整符号。

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.

献世佛 2024-10-10 19:47:50

听起来你想做无符号整数算术,然后将结果填充到有符号整数中:

unsigned char a = 19;
unsigned char b = 12;

signed char c = (signed char)(a*b);

应该给你你正在寻找的东西。如果没有,请告诉我们。

It sounds like you want to do unsinged integer arithmetic, then stuff the result into a signed integer:

unsigned char a = 19;
unsigned char b = 12;

signed char c = (signed char)(a*b);

should give you what you're looking for. Let us know if it doesn't.

独木成林 2024-10-10 19:47:50

使用更大的数据类型。使用GMP,您将拥有可能需要的所有空间。

Use bigger datatypes. With GMP you will have all the space you probably need.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文