浮点值不准确。
这几乎就是问题的答案。存在有限精度,这意味着某些数字无法准确表示。
某些语言在语言级别支持任意精度的数字类型/有理数/复数等,但不支持 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 10de
现在您仍然只能记住 5 个数字a, b, c, d, e,但您现在可以表示更广泛的数字,甚至是非整数。例如:
123 x 100 = 123.0
123 x 103 = 123,000.0
123 x 106 = 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 位。
也可以看看