将 uint32_t 转换为 uint64_t 会产生不同的值?
casting uint32_t to uint64_t results in different value?
使用 Visual Studio 2015 C++,14.0.25431.01 更新 3。我的代码出现意外行为。使用 64 位编译和 运行,发布:
#include <iostream>
#include <stdint.h>
int main(int, char**) {
for (uint32_t i = 1; i < 3; ++i) {
uint32_t a = i * 0xfbd1e995;
uint64_t b = a;
std::cout << a << " 32bit" << std::endl;
std::cout << b << " 64bit" << std::endl;
}
}
我希望 a
和 b
具有相同的值,但是当我 运行 时,我得到这个输出:
4224838037 32bit
4224838037 64bit
4154708778 32bit
8449676074 64bit
编译器似乎用 64 位乘法替换了 32 位乘法。是否允许这样做,或者这是一个编译器错误? g++ 和 clang 都给出了我期望的数字。
编辑:我已经用具有相同问题的更简单版本更新了我的代码。另外,I've just submitted a bug report.
我可以在 VS2010 上重现,直接原因是:
add ebx, 5BD1E995h ; this is x
add rdi, 5BD1E995h ; this is a 64bit version of x
因为是64位加法,所以只会进位到高32位。这至少比想出一个 64 位乘法更有意义,它可能是归纳变量消除中的一个极端情况,但这只是推测。
同样有趣的是,它甚至不会通过错误编译来保存演员表。正确的值就在 rbx
.
中
看来这个修补程序解决了这个问题,至少对于 VS 2015:
但似乎 VS 2008、2010、2013 仍受此错误影响。
来源:
使用 Visual Studio 2015 C++,14.0.25431.01 更新 3。我的代码出现意外行为。使用 64 位编译和 运行,发布:
#include <iostream>
#include <stdint.h>
int main(int, char**) {
for (uint32_t i = 1; i < 3; ++i) {
uint32_t a = i * 0xfbd1e995;
uint64_t b = a;
std::cout << a << " 32bit" << std::endl;
std::cout << b << " 64bit" << std::endl;
}
}
我希望 a
和 b
具有相同的值,但是当我 运行 时,我得到这个输出:
4224838037 32bit
4224838037 64bit
4154708778 32bit
8449676074 64bit
编译器似乎用 64 位乘法替换了 32 位乘法。是否允许这样做,或者这是一个编译器错误? g++ 和 clang 都给出了我期望的数字。
编辑:我已经用具有相同问题的更简单版本更新了我的代码。另外,I've just submitted a bug report.
我可以在 VS2010 上重现,直接原因是:
add ebx, 5BD1E995h ; this is x
add rdi, 5BD1E995h ; this is a 64bit version of x
因为是64位加法,所以只会进位到高32位。这至少比想出一个 64 位乘法更有意义,它可能是归纳变量消除中的一个极端情况,但这只是推测。
同样有趣的是,它甚至不会通过错误编译来保存演员表。正确的值就在 rbx
.
看来这个修补程序解决了这个问题,至少对于 VS 2015:
但似乎 VS 2008、2010、2013 仍受此错误影响。
来源: