[英]Strange unsigned long long int behavior
我正在使用unsigned long long int进行一些计算,但是
std::cout << std::setprecision(30) << 900000000000001i64+4*pow(10, 16);
输出: 40900000000000000
和这个
std::cout << std::setprecision(30) << 900000000000011i64+4*pow(10, 16);
输出: 40900000000000008
现在,我不知道发生了什么事我试图消除i64
尝试打印4*pow(10, 16)
给出正确的结果40000000000000000
也试图打印40900000000000011
直接,它打印正确的结果。 对于10 ^ 14的幂,它可以正常工作,但是此后它开始表现异常。
有人可以解释发生了什么吗?
您得到此尴尬结果的原因是因为丢失了double
类型的最低有效位的值。 double
尾数只能容纳大约15个十进制数字和正好52个二进制数字( Wiki )。
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;
将产生结果:
40900000000000000
40900000000000000
40900000000000000
40900000000000000
40900000000000008
40900000000000008
40900000000000008
40900000000000008
40900000000000008
40090000000000008
注意如何将值四舍五入为2 3 。
请尝试以下代码(请注意此处的显式类型转换)。
typedef unsigned long long ULONG64; //Not a must, but just for code clarity
std::cout << std::setprecision(30) << 900000000000001i64 + (ULONG64)(4 * pow(10, 16));
//output -> 40900000000000001
std::cout << std::setprecision(30) << 900000000000011i64 + (ULONG64)(4 * pow(10, 16));
//output -> 40900000000000011
您必须告诉编译器对pow(...)函数返回的结果进行显式类型转换(转换为ULONG64),类型为double。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.