我有以下代码:
UINT64 time1 = 215510*10000;
UINT64 time2 = (UINT64)(215510 * 10000);
当打印它们或在Watch中时,结果是:
time1 = 18446744071569684320
time2 = 18446744071569684320
其实我知道怎么做到这里。我们必须使用以下代码之一才能得到正确的答案(以下3个版本都可以):
UINT64 time3 = (UINT64)215510 * 10000;
UINT64 time4 = 215510 * (UINT64)10000;
UINT64 time5 = (UINT64)215510 * (UINT64)10000;
但为什么前两行不能给出正确答案?
答案 0 :(得分:11)
这是因为你通过乘以两个结果大于32位的32位数来调用整数溢出。您需要先转换为64位,如您所示。
答案 1 :(得分:9)
因为像215510
这样的文字常量通常标准C ++中的int
(不是long
)。它与Visual Studio无关(至少如果g++
- s有32位,它应该与GCC又名int
的其他编译器相同),所以215510 * 10000
是也是int
。尝试215510L * 10000
让一个被乘数为long
(因此该产品也是long
- 如果long
- s仍为32位,则不会更改产品! ),甚至215510LL
使其成为long long
或使用明确的演员(int64_t)215510
......
在您的平台上,int
可能是32位。所以签名的INT_MAX
是2147483647
(2 31 - 1)。
Keith Thompson正确地评论了
整数常量的类型是相应列表的第一个 其值可以表示。
per(C11标准§6.4.4.1项5或)C ++ 11标准§2.14.2项2.因此,在16位int
- s和32位{{1}的实现上} -s long
是一个215510
字面常量(因为215510> 32767,它将是long
....)。
与我所认为的相反,文字积分常数的类型不是由它的后缀 - 或者缺乏它 - 单独定义,而是由它的值定义!
答案 2 :(得分:3)
在C ++中,非整数整数文字的类型为int
,long int
或long long int
,无论哪个是第一个可以表示其值的文件。 (long long int
是该语言的最新成员。)
可能在您的系统上,215510
和10000
都是int
类型,可能是32位类型。
表达式(通常)由它们自己评估,而不考虑它们出现的上下文。因此,表达式215510*10000
被评估为int
。由于数学结果超出INT_MAX
,结果未定义,但可能是-2139867296
。
当该值转换为64位无符号类型时,它会回绕,产生18446744071569684320
(略小于2 64 )。