免责声明(由Toby Speight建议):虽然IEEE 754表示法非常常见,但实现可以使用任何其他符合语言要求的表示法。
双精度浮点数的表示形式为mantissa * 2^exponent
,即一些位用于浮点数的小数部分。
bits range precision
float 32 1.5E-45 .. 3.4E38 7- 8 digits
double 64 5.0E-324 .. 1.7E308 15-16 digits
long double 80 1.9E-4951 .. 1.1E4932 19-20 digits
![IEEE 754双精度类型示意图](https://istack.dev59.com/jYFQR.webp)
小数部分也可以通过使用指数来表示整数,指数将小数点后的所有数字都移除。
例如:2,9979 · 10^4 = 29979。
由于常规的int
通常为32位,因此您可以将所有的int
表示为double类型,但对于64位整数来说显然不再适用。更准确地说(正如LThode在评论中指出的):IEEE 754双精度类型可保证最多53个二进制位(52个有效数字位+1个隐式前导位)。
答案:32位int合适,64位int不合适。
(这适用于服务器/台式机通用CPU环境,但其他架构可能会有所不同。)
实际答案:如Malcom McLean所说,64位double类型对于几乎所有可能计数实际事物的整数都是足够的。
对于实证倾向的人,请尝试这个:
#include <iostream>
#include <limits>
using namespace std;
int main() {
double test;
volatile int test_int;
for(int i=0; i< std::numeric_limits<int>::max(); i++) {
test = i;
test_int = test;
if (test_int != i)
std::cout<<"found integer i="<<i<<", test="<<test<<std::endl;
}
return 0;
}
成功时间:0.85 内存:15240 信号:0
子问题:关于分数差异的问题。是否可能存在一个整数,它转换为一个浮点数时,其值偏离正确值,但是由于四舍五入而再次转换为相同的整数?
答案是否定的,因为任何转换回和转换前值相同的整数,在双精度浮点数中实际上表示的是相同的整数值。对我来说,最简单的解释(由 ilkkachu 提出)是使用指数 2 ^ exponent
,步长必须始终是二的幂次方。因此,在超过最大的52(+1 sign)位整数后,从来没有两个距离小于2的双精度浮点数,这解决了舍入问题。
int
和double
可以表示的值范围由实现定义,但是double
绝不能支持它所能表示的所有整数值。实际答案是 "这取决于情况"。 - Peternumeric_limits<double>::digits
和nextafter
即可。 - Howard Hinnant