C 在方程内溢出
C overflows inside an equation?
a + b
如我预期的那样将 255 溢出回 4,然后c / 2
如我预期的那样给出 2。但是,为什么最后一个示例在评估相同的两个步骤时没有溢出呢?
我猜内部计算值存储了更多位,然后在执行作业时仅截断为 8 位。在这种情况下,极限在哪里,它必须在某个时候溢出?
uint8_t a = 250;
uint8_t b = 10;
uint8_t c = (a + b);
uint8_t d = c / 2;
uint8_t e = (a + b) / 2;
std::cout << unsigned(c) << ", " << unsigned(d) << ", " << unsigned(e) << "n";
4, 2, 130
这称为积分提升。操作本身在 CPU 的本机整数类型 int
中完成,该类型可以容纳大于 255 的数字。在a+b
情况下,结果必须存储在uint8_t
中,这就是截断的地方。在最后一种情况下,首先有一个除法作为int
完成,结果可以完美地存储在uint8_t
中。
a+b
给出的值 260,该值未分配给任何uint8_t
类型,因此在最后一种情况下您很好。仅当您将任何大于 255 的值设置为 uint8_t
时,才会出现溢出。
在以下(a + b)
不溢出的情况下,编译器将a
和b
识别为整数类型,因此加法会产生整数类型,此表达式的结果不受表达式中项或因子大小的限制。
假设变量的类型(如 a
或 b
(在这种情况下将结果限制为仅该类型。虽然有可能,但几乎不可能使用这样的语言。想象一下五个变量,当不考虑类型时,它们的总和为 500,即这个。
uint8_t a = 98;
uint8_t b = 99;
uint8_t c = 100;
uint8_t d = 101;
uint8_t e = 102;
上述变量的总和 == 500。现在。。。在下面,任何表达式的结果都不能超过其中一个项的大小...
int incorrect = (a + b + c + d + e);
在这种情况下(a + b + c) == 41
则(41 + d + e)
== 244。这是一个荒谬的答案..大多数人认可的替代方案即
(98 + 99 + 100 + 101 + 102) == 500;
这是类型转换存在的原因之一。
表达式中的中间结果不应受表达式中的项或因素的限制,而应受结果类型(即左值(的限制。
@atturri是正确的。 以下是 x86 机器语言中变量发生的情况:
REP STOS DWORD PTR ES:[EDI]
MOV BYTE PTR SS:[a],0FA
MOV BYTE PTR SS:[b],0A
MOVZX EAX,BYTE PTR SS:[a] ; promotion to 32bit integer
MOVZX ECX,BYTE PTR SS:[b] ; promotion to 32bit integer
ADD EAX,ECX
MOV BYTE PTR SS:[c],AL ; ; demotion to 8bit integer
MOVZX EAX,BYTE PTR SS:[c]
CDQ
SUB EAX,EDX
SAR EAX,1
MOV BYTE PTR SS:[d],AL
MOVZX EAX,BYTE PTR SS:[a]
MOVZX ECX,BYTE PTR SS:[b]
ADD EAX,ECX
CDQ
SUB EAX,EDX
SAR EAX,1
MOV BYTE PTR SS:[e],AL
- 为什么在全局范围内使用"extern int a"似乎不行?
- 内置函数可查看CPP中的成员变量
- 在某些循环内使用vector.push_back时出现分段错误
- 错误:未在此范围内声明'reverse'
- 内联映射初始化的动态atexit析构函数崩溃
- 不同翻译单元中不可重载的非内联函数定义
- 'short int'持有的值溢出,但"自动"不会溢出?
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 大于65535的C++数组[size]引发不一致的溢出
- 头文件、宏和内联函数c++
- 内联函数中具有内部链接的全局变量
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- C++在变量给定的指定时间内关闭电脑
- C++中无符号字符溢出
- 线性丢番图方程 - 求给定区间内的解数和解
- 为什么内置类型的对象上的溢出会导致异常/未定义的行为?
- 以下程序中最大 int 1000 000(在 int 范围内)的整数溢出
- 为什么 C 和 C++ 没有内置方法来检查整数溢出?
- C 在方程内溢出
- 在main内声明的数组引发堆栈溢出,在main外声明的数组则不会