默认情况下它们不以这种方式存储的原因是可以适合固定位集的有效值范围更小。您的float
班级可以存储 1/MAXINT 和 MAXINT(正负)之间的数字。AC/C++float
可以表示 1E+37 和 1E-37(加号或减号)之间的数字。换句话说,一个标准float
可以表示比你的值大 26 个数量级和小 26 个数量级的值,尽管它占用了一半的位数。通常,能够表示非常大和非常小的值比非常精确更方便。尤其如此,因为四舍五入往往会给我们提供像 1/3 这样的小分数的正确答案。在 g++ 中,以下给出 1:
std::cout << ((1.0/3.0) * 3.0) << std::endl;
请记住,C++ 中的类型具有固定的位大小。因此,32 位数据类型最多具有 MAX_UINT 值。如果你改变它的表示方式,你只是改变了可以精确表示的值,而不是增加它们。你不能塞得更多,因此不能“更精确”。你可以用能够精确表示 1/3 来换取不能精确表示其他值,例如 5.4235E+25。
确实,您float
可以更精确地表示 1E-9 和 1E+9 之间的值(假设为 32 位整数),但代价是完全无法表示超出此范围的值。更糟糕的是,虽然标准float
始终具有 6 位精度,但您的精度float
会根据值接近零的程度而有所不同。(请注意,您使用的是两倍的位float
。)
(我假设 32 bit int
s。同样的论点适用于 64 bit int
s。)
编辑:另请注意,人们使用的大多数数据float
s 无论如何都不精确。如果您正在从传感器读取数据,那么您已经获得了不精确性,因此即将“完美”地表示该值是没有意义的。如果您float
在任何类型的计算环境中使用 a ,那都没关系。如果您的目的是在屏幕的 1/3 处显示一些文本,那么完美地描述“1/3”是没有意义的。
唯一真正需要完美精确度的人是数学家,他们通常有软件可以做到这一点。很少有人需要超出double
给定范围的精度。