long long int ans = a*b 与 long long int ans = (long long int) a*b 的区别

4

我写了一段代码:

int a = 1000000000, b = 1000000000;
long long int ans = a * b;
cout << ans << '\n';

这段代码造成了溢出(overflow)。我知道 a * b 是问题的原因,但是我已经使用了 long long int 变量来存储 a*b。 但请看下面的代码:

int a = 1000000000, b = 1000000000;
long long int ans = (long long int)a * b;
cout << ans << '\n';

它正常工作,没有造成溢出。在计算时,是否会创建临时变量来保存值?请解释这种奇怪的溢出背后的原因。


第一个片段溢出的原因是a * b被计算为int(操作数的类型),这并不重要,即使在计算后存储该结果的变量类型更宽。 - Bob__
“a * b被计算为int” - 但是在计算过程中数字存储在哪里?它存储在不同的临时int变量中还是其中一个变量a,b中?@Bob__ - Jahirul Sarker
1
这发生在CPU寄存器中,实际步骤取决于硬件/ 微码。例如,请参见此处,其中值在imul之前或之后(在寄存器中)被扩展。 - Bob__
我会查看什么是隐式转换,特别是整数提升。 - MatG
1个回答

2
这将创建两个临时变量(long long int)a(long long int)b。第二次转换是隐式的。
如果硬件有一个32*32->64乘法,实际编译器可能不会费心进行转换,但官方上要求必须进行转换。在64位硬件上,当您将int加载到64位寄存器中时,这基本上是免费的。

实际上,在将乘积赋值给已声明变量之前,它在哪里保存计算出的乘积(a*b)? - Jahirul Sarker
在实践中,CPU寄存器中。在优化的构建中,该寄存器将是用于“ans”的相同寄存器,因此赋值不需要指令。 - MSalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接