根据您的平台,int 可能是 32 位或 64 位宽。
来自[basic.fundamental]/2 和[basic.fundamental]/3 [摘录,强调我的]:
[basic.fundamental]/2
有五种标准有符号整数类型:“signed char”,
“short int”、“int”、“long int”和“long long int”。在这个
列表,每种类型提供的存储空间至少与前面的相同
它在列表中。 [...] 普通 ints 有建议的自然尺寸
通过执行环境的架构;另一个签名
提供整数类型以满足特殊需求。
[basic.fundamental]/3
对于每个标准的有符号整数类型,都存在一个
对应的(但不同的)标准无符号整数类型:
“unsigned char”、“unsigned short int”、“unsigned int”、
“unsigned long int”和“unsigned long long int”,每个
占用相同的存储量并具有相同的对齐方式
要求为对应的有符号整数类型; [...]
有符号和无符号整数类型应满足约束
在 C 标准第 5.2.4.2.1 节中给出。
我们可以去C11 Standard draft [摘录,强调我的]:
5.2.4.2.1 整数类型的大小<limits.h>
[...] 它们的实现定义的值应等于或大于
幅度(绝对值)与所示的相同,符号相同。
[...]
-
int 类型对象的最大值:INT_MAX +32767
[...]
如果不了解目标/架构细节,这对我们没有帮助,但是,为了简化您的问题,让我们考虑使用固定宽度有符号整数的示例,并注意以下示例“很好”(在这种情况下):
#include <cstddef>
#include <math.h>
int main() {
double what;
for (int32_t i = 1; i < (int32_t)pow(10, 4); i++)
{
what = (i + i) / (i * i) - i;
}
(void)what;
return 0;
}
而对于我尝试过的特定处决,以下结果会导致“浮点异常”(UB;龙可能会飞出我们的鼻子,见下文):
#include <cstddef>
#include <math.h>
int main() {
double what;
for (int32_t i = 1; i < (int32_t)pow(10, 5); i++)
{
what = (i + i) / (i * i) - i;
}
(void)what;
return 0;
}
这里的关键是int32_t 的最大值是2,147,483,647,这意味着i * i 将溢出pow(10, 5) 大小的值。有符号整数溢出是未定义的行为 (UB),从那里开始任何事情都会发生。在这种情况下,可能是 UB,巧合,从表达式 i * i 的溢出中产生一个值 0,这反过来又导致表达式中除以零(再次是 UB) (i + i) / (i * i),更巧合,很可能是浮点异常的根源。
我在这里强调巧合,因为超出 UB 的任何点都会成为逻辑分析的无用目标;编译器供应商可能会假设我们从来没有 UB 并且一旦我们进入 UB 域就会做任何事情。我们看到的任何结果都应视为巧合,除非您在特定目标架构和硬件上使用 C++ 的某些非标准方言工作,例如有符号整数溢出等特殊情况可能被定义为非标准实现定义(因此由特定实现指定)而不是 UB。