c++ - 无符号整数背后的想法

标签 c++ unsigned-integer

<分区>

Possible Duplicate:
What happens if I assign a negative value to an unsigned variable?

我是 C++ 的新手,我想知道如何使用无符号类型。对于 unsigned int 类型,我知道它可以取 0 到 4294967296 之间的值。但是当我想按如下方式初始化 unsigned int 类型时:

unsigned int x = -10;
cout << x;

输出看起来像4294967286 得到这个 output = max value - 10。所以我想了解内存中发生了什么?在这个计算继续进行的同时,正在进行什么样的过程?感谢您的回答。

最佳答案

您遇到了环绕行为。

无符号类型是循环的(另一方面,有符号类型可能是也可能不是循环的,但它是您不应该依赖的未定义行为)。也就是说,比最小可能值小1就是最大可能值。您可以使用以下代码段自行演示:

int main()
{
    unsigned int x = 5;
    for (int i = 0; i < 10; ++i) cout << x-- << endl;
    return 0;
}

您会注意到,在达到零后,x 的值跳到 2^32-1,即最大可表示值。减去预期的进一步行为。

当您从无符号 0 中减去 1 时,位模式将按以下方式更改:

0000 0000 0000 0000 0000 0000 0000 0000 // before (0)
1111 1111 1111 1111 1111 1111 1111 1111 // after  (2^32 - 1)

对于无符号数,负数被视为从零减去正数。所以 (unsigned int) -10 将等于 ((unsigned int) 0) - ((unsigned int) 10)

我喜欢将其视为一个无符号整数,它是一个更高精度的任意值的最低 32 位。像这样:

v imaginary high order bit
1 0000 0000 0000 0000 0000 0000 0000 0000 // before (2^32)
0 1111 1111 1111 1111 1111 1111 1111 1111 // after  (2^32 - 1)

unsigned int 在这些溢出情况下的行为与从 256 中减去 1 时 unsigned int 的低 8 位的行为完全相同。查看 unsigned char(1 字节)更有意义像这样,因为如果转换为 unsigned char,值 0 和 256 是相等的,因为有限的精度会丢弃额外的位。

0 0000 0000 0000 0000 0000 0001 0000 0000 // before (256)
0 0000 0000 0000 0000 0000 0000 1111 1111 // before (255)

正如其他人所指出的,这称为模运算。使用更高精度的值有助于可视化环绕时所做的转换,因为您屏蔽了高阶位。它是什么并不重要,所以它可以是任何东西,它只是被丢弃了。整数是模数超过 2^32 的值,因此 2^32 的任何倍数在整数空间中都等于零。这就是为什么我可以假装最后有一个额外的位。

模数运算有自己专用的运算符,以防您需要在程序中计算除 2^32 以外的数字时,如以下语句中所用:

int forty_mod_twelve = 40 % 12;
// value is 4: 4 + n * 12 == 40 for some whole number n

对 2 的幂(如 2^32)的模运算直接简化为屏蔽掉高阶位,如果您采用 64 位整数并计算它对 2^32 的模,则该值将与您完全相同已将其转换为无符号整数。

01011010 01011100 10000001 00001101 11111111 11111111 11111111 11111111 // before
00000000 00000000 00000000 00000000 11111111 11111111 11111111 11111111 // after

程序员喜欢使用此属性来加快程序速度,因为它很容易砍掉一些位数,但执行模运算要困难得多(与除法一样难)。

这有意义吗?

关于c++ - 无符号整数背后的想法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12786579/

相关文章:

c - 'u' 和整数有什么用

types - 为什么 Kotlin 不支持无符号整数?

c++ - 为什么 size_t 是无符号的?

byte - 寻址 32 个字节需要多少位?

java - Java 中的 Unsigned int(原始)和 Integer(对象)用法

c++ - 程序开始信号 Qt C++

c# - Kinect 流保存

c++ - C++11 中的 P99_FOR

c++ - 更改 ld-linux 位置

c++ - 将模板参数约束为仅接受带有 C++20 概念的 std::vector 和 std::list