Sar*_*ngh 1 c++ unsigned-long-long-int
我使用unsigned long long int进行一些计算但是
std::cout << std::setprecision(30) << 900000000000001i64+4*pow(10, 16);
Run Code Online (Sandbox Code Playgroud)
给出输出:40900000000000000
还有这个
std::cout << std::setprecision(30) << 900000000000011i64+4*pow(10, 16);
Run Code Online (Sandbox Code Playgroud)
给出输出:40900000000000008
现在我不知道发生了什么我尝试删除i64尝试打印4*pow(10, 16)给出正确的结果40000000000000000也尝试40900000000000011直接打印,它打印正确的结果.它适用于10 ^ 14的功率但在此之后它开始表现得很奇怪.
有人可以解释发生了什么吗?
你得到这个尴尬结果的原因是因为丢失了double类型中最低有效位的值.double尾数只能容纳15个十进制数字和52个二进制数字(维基).
900000000000001i64+4*pow(10, 16)将被转换为双重修整所有低位.在你的情况下,有3个.
例:
std::cout << std::setprecision(30);
std::cout << 900000000000001i64 + 4 * pow(10, 16) << endl;
std::cout << 900000000000002i64 + 4 * pow(10, 16) << endl;
std::cout << 900000000000003i64 + 4 * pow(10, 16) << endl;
std::cout << 900000000000004i64 + 4 * pow(10, 16) << endl;
std::cout << 900000000000005i64 + 4 * pow(10, 16) << endl;
std::cout << 900000000000006i64 + 4 * pow(10, 16) << endl;
std::cout << 900000000000007i64 + 4 * pow(10, 16) << endl;
std::cout << 900000000000008i64 + 4 * pow(10, 16) << endl;
std::cout << 900000000000009i64 + 4 * pow(10, 16) << endl;
Run Code Online (Sandbox Code Playgroud)
会产生结果:
40900000000000000
40900000000000000
40900000000000000
40900000000000000
40900000000000008
40900000000000008
40900000000000008
40900000000000008
40900000000000008
40090000000000008
Run Code Online (Sandbox Code Playgroud)
请注意值如何舍入为2 3.