C++具有导致溢出的混合整数类型的算术
C++ Arithmetic With Mixed Integral Types That Causes Overflow
我在VC++2010中做了一些测试,混合了不同大小的操作数,导致添加操作溢出:
int _tmain(int argc, _TCHAR* argv[])
{
__int8 a=127;
__int8 b=1;
__int16 c=b+a;
__int8 d=b+a;
printf("c=%d,d=%dn",c,d);
return 0;
}
//result is: c=128, d=-128
我不明白为什么c==128! 我的理解是,在这两个加法中,b+a 仍然被认为是 2 个有符号 8 位变量的加法。所以结果是溢出,即 -128。 之后,对于第一次赋值操作,结果将提升为 16 位有符号 int,c 仍应获得 16 位 -128 值。 我的理解正确吗? c++标准有点难以阅读。第 4 章似乎在谈论整数提升,但我找不到与此特定示例相关的任何内容。
我的理解是,在这两个加法中,b+a 仍然被认为是 2 个有符号 8 位变量的加法。所以结果是溢出,即 -128。
不,促销发生在评估+
之前,而不是之后。当a
和b
均为正时,就会发生加法。两个数字都提升到 int
s 以进行加法,作为两个正数相加,然后转换为 16 位短数。在过程中的任何一点,结果都不会因溢出而变为负数,因此最终结果为 128。
可以说,这是有道理的:a
和b
的行为与数学中两个数字的行为相匹配,使语言从业者更直观。
这是不可或缺的推广。
1 如果整数转换秩 (4.13) 小于 int 的整数类型,则 bool、char16_t、char32_t 或 wchar_t 以外的整数类型的 prvalue 可以转换为 int 类型的 prvalue,如果 int 可以表示源类型的所有值;否则,源 prvalue 可以转换为无符号 int 类型的 prvalue。 [§ 4.5]
在此声明中
__int16 c=b+a;
首先,所有
char
和short int
值都会自动提升为int
。这个过程称为整体提升。接下来,将所有操作数转换为最大操作数的类型,这称为类型提升。[赫伯特·希尔德]
变量 b
和 a
的值将提升为 int
,然后对它们应用操作。
在二进制补码整数表示中,有符号值通过设置最高位来表示。 这允许机器使用相同的指令加减二进制整数,而不管整数是否有符号。
a = 127 == 0x7F == 0b01111111
+ b = 1 == 0x01 == 0b00000001
-------------------------------
c = 128 == 0x80 == 0b10000000
d =-128 == 0x80 == 0b10000000
变量c
和d
可能具有不同的类型,但不同类型的整数只是对单个二进制值的不同解释。 正如您在上面看到的,二进制值适合 8 位就好了。 由于该标准要求数学表达式的项在完成任何数学运算之前为零或符号扩展(提升)到机器字的大小,并且两个操作数都不会进行符号扩展,因此无论操作数是什么类型,结果始终是0b10000000
的。
总之,结果之间的区别在于,对于 16 位整数,符号位是0b1000000000000000
(a+b
没有),而对于 8 位整数,符号位是0b10000000
(a+b
确实有)。
- 如何反转整数参数包
- enum是C++中的宏变量还是整数变量
- 努力将整数转换为链表。不知道我在这里做错了什么
- 整数不会重复超过随机数
- 在C++中手动调整数组大小
- 检查输入是否不是整数或数字
- C++使用整数的压缩数组初始化对象
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 如何只允许用户输入正整数
- 为什么C++标准指定有符号整数在具有混合符号的二进制操作中强制转换为无符号整数
- 将整数算术与布尔值混合 - Z3 证明器
- 查找混合整数程序的绑定约束
- 在 C/C++ 中,混合类型整数数学所需的最小类型向上转换是多少?
- C++具有导致溢出的混合整数类型的算术
- 将标准::时间与随机整数混合
- 从包含混合整数、字母和空格C++的文件中读取整数
- 混合符号整数数学取决于变量大小
- 在C++中从文件中读取整数和字符的混合