乐趣区

关于java:01-02-03

Floating Point Math

Your language isn’t broken, it’s doing floating point math. Computers can only natively store integers, so they need some way of representing decimal numbers. This representation is not perfectly accurate. This is why, more often than not, 0.1 + 0.2 != 0.3.

Why does this happen?

It’s actually rather interesting. When you have a base-10 system (like ours), it can only express fractions that use a prime factor of the base. The prime factors of 10 are 2 and 5. So 1/2, 1/4, 1/5, 1/8, and 1/10 can all be expressed cleanly because the denominators all use prime factors of 10. In contrast, 1/3, 1/6, 1/7 and 1/9 are all repeating decimals because their denominators use a prime factor of 3 or 7.

In binary (or base-2), the only prime factor is 2, so you can only cleanly express fractions whose denominator has only 2 as a prime factor. In binary, 1/2, 1/4, 1/8 would all be expressed cleanly as decimals, while 1/5 or 1/10 would be repeating decimals. So 0.1 and 0.2 (1/10 and 1/5), while clean decimals in a base-10 system, are repeating decimals in the base-2 system the computer uses. When you perform math on these repeating decimals, you end up with leftovers which carry over when you convert the computer’s base-2 (binary) number into a more human-readable base-10 representation.

Below are some examples of sending .1 + .2 to standard output in a variety of languages.

翻译如下:

浮点数学

您的语言没有坏,正在做浮点运算。计算机只能本地存储整数,因而它们须要某种示意十进制数字的形式。此示意并不齐全精确。这就是为什么(通常不是)的起因 0.1 + 0.2 != 0.3

为什么会这样?

实际上,这很乏味。当您有一个以 10 为底的零碎(如咱们的零碎)时,它只能示意应用该底数的质数的分数。10 的素数是 2 和 5。因而,因为分母都应用 10 的素数,所以 1 / 2、1 / 4、1 / 5、1 / 8 和 1 /10 都能够分明地示意。/ 3、1 / 6、1 / 7 和 1 / 9 都是反复的小数,因为它们的分母应用 3 或 7 的质数。

在二进制(或以 2 为基数)中,惟一的质数是 2,因而您只能分明地表白分母只有 2 作为质数的分数。以二进制模式,1 / 2、1 / 4、1 / 8 都将洁净地示意为小数,而 1 / 5 或 1 /10 将反复小数。因而,在以 10 为基数的零碎中应用洁净的小数时,0.1 和 0.2(1/10 和 1 /5)在计算机应用的以 2 为基数的零碎中反复小数。当您对这些反复的小数进行数学运算时,最终会剩下余数,当您将计算机的以 2 为底的(二进制)数字转换为更易于了解的以 10 为底的示意模式时,这些余数就会保留下来。

以下是应用 .1 + .2 多种语言发送到规范输入的一些示例。

在 Java 中的状况:Java 应用 BigDecimal 类内置了对任意精度数字的反对。

所有语言中的状况:

参考:《2020 最新 Java 根底精讲视频教程和学习路线!》

链接:Floating Point Math

退出移动版