浮点值不准确。
这几乎就是问题的答案。存在有限精度,这意味着某些数字无法准确表示。
某些语言在语言级别支持任意精度的数字类型/有理数/复数等,但不支持 Javascript。C 和 Java 都没有。
IEEE 754 标准浮点值不能0.1
精确表示。这就是为什么必须非常小心地使用美分等进行数值计算。有时,解决方案是将美分值存储为整数,而不是将美元存储为浮点值。
“浮点”概念,以 10 为底的模拟
要了解为什么浮点值不精确,请考虑以下模拟:
- 你只有足够的记忆力来记住 5 位数字
- 您希望能够在尽可能广泛的范围内表示值
在代表整数,你可以在该范围内代表的数值-99999
来+99999
。超出这些范围的值需要您记住 5 位以上的数字,这(就本示例而言)您无法做到。
现在您可以考虑定点表示,例如abc.de
。现在,您可以在范围代表值-999.99
,以+999.99
高达2个位数的精度,例如3.14
,-456.78
等等。
现在考虑一个浮点版本。在你的足智多谋中,你想出了以下方案:
n = abc x 10
de
现在您仍然只能记住 5 个数字a
, b
, c
, d
, e
,但您现在可以表示更广泛的数字,甚至是非整数。例如:
123 x 10
0
= 123.0
123 x 10
3
= 123,000.0
123 x 10
6
= 123,000,000.0
123 x 10
-3
= 0.123
123 x 10
-6
= 0.000123
这就是“浮点”这个名字的由来:上面例子中的小数点“四处浮动”。
现在您可以表示范围广泛的数字,但请注意,您不能表示0.1234
. 你也不能代表123,001.0
。事实上,有很多value是你无法代表的。
这几乎就是浮点值不精确的原因。它们可以表示范围很广的值,但由于您仅限于固定数量的内存,您必须牺牲精度以换取数量级。
更多技术
在abc
被称为有效数,又名系数/尾数。的de
是指数,又名规模/特性。像往常一样,计算机使用基数 2 而不是 10。除了记住“数字”(位,真的),它还必须记住有效数和指数的符号。
单精度浮点类型通常使用 32 位。双精度通常使用 64 位。
也可以看看