为什么十进制数不能完全用二进制表示? [英] Why can't decimal numbers be represented exactly in binary?
问题描述
我不明白的是,从数学的角度来看,为什么是小数点右边的数字例如,数字61.0有一个确切的二进制表示,因为任何数字的整数部分总是精确的。但数字6.10不是确切的。我所做的只是把小数点后移一位,突然间我从Exactopia变成了Inexactville。在数学上,这两个数字之间应该没有内在的区别 - 它们只是数字。
相比之下,如果我将小数点位置移到另一个方向产生数字610,我仍然在Exactopia。我可以继续沿着这个方向(6100,610000000,610000000000000),他们仍然是确切的,确切的,确切的。但是一旦小数点超过某个阈值,这些数字就不再准确。
发生了什么事?
编辑:为了澄清,我想远离关于IEEE等行业标准表示的讨论,坚持我认为是数学上的纯的方式。在基数10中,位置值是:
... 1000 100 10 1 1/10 1/100 ...
在二进制中,它们是:
... 8 4 2 1 1/2 1/4 1/8 ...
这些数字也没有任何限制。
十进制数可以 完全表示,如果你有足够的空间 - 只是不浮点二进制点数。如果你使用浮点十进制点类型(例如.NET中的 System.Decimal
),那么很多值不能完全用二进制表示浮点可以被精确地表示。
让我们从另一个角度来看 - 在基数10中,您可能会感到满意,但不能准确表达1/3。这是0.3333333 ...(经常性)。您不能将0.1表示为二进制浮点数的原因完全是由于相同的原因。你可以完全表示3,9和27,但不能是1/3,1/9或1/27。问题是,3是一个素数这不是10的因素。当你想把一个数乘以3时,这不是问题:你总是可以乘以一个整数而不会遇到问题。但是,如果你用一个数字来区分一个数字,而这个数字不是你的基数,那么你可能会遇到麻烦(如果你试图将1除虽然0.1通常被用作精确十进制数的最简单的例子,但它不能完全用二进制浮点数表示,可以说0.2是一个更简单的例子,因为它是1/5 - 5是导致十进制和二进制之间的问题的主要元素。
处理有限表示的问题:
一些浮点小数点类型具有固定大小,如 There have been several questions posted to SO about floating-point representation. For example, the decimal number 0.1 doesn't have an exact binary representation, so it's dangerous to use the == operator to compare it to another floating-point number. I understand the principles behind floating-point representation. What I don't understand is why, from a mathematical perspective, are the numbers to the right of the decimal point any more "special" that the ones to the left? For example, the number 61.0 has an exact binary representation because the integral portion of any number is always exact. But the number 6.10 is not exact. All I did was move the decimal one place and suddenly I've gone from Exactopia to Inexactville. Mathematically, there should be no intrinsic difference between the two numbers -- they're just numbers. By contrast, if I move the decimal one place in the other direction to produce the number 610, I'm still in Exactopia. I can keep going in that direction (6100, 610000000, 610000000000000) and they're still exact, exact, exact. But as soon as the decimal crosses some threshold, the numbers are no longer exact. What's going on? Edit: to clarify, I want to stay away from discussion about industry-standard representations, such as IEEE, and stick with what I believe is the mathematically "pure" way. In base 10, the positional values are: In binary, they would be: There are also no arbitrary limits placed on these numbers. The positions increase indefinitely to the left and to the right. Decimal numbers can be represented exactly, if you have enough space - just not by floating binary point numbers. If you use a floating decimal point type (e.g. Let's look at it another way - in base 10 which you're likely to be comfortable with, you can't express 1/3 exactly. It's 0.3333333... (recurring). The reason you can't represent 0.1 as a binary floating point number is for exactly the same reason. You can represent 3, and 9, and 27 exactly - but not 1/3, 1/9 or 1/27. The problem is that 3 is a prime number which isn't a factor of 10. That's not an issue when you want to multiply a number by 3: you can always multiply by an integer without running into problems. But when you divide by a number which is prime and isn't a factor of your base, you can run into trouble (and will do so if you try to divide 1 by that number). Although 0.1 is usually used as the simplest example of an exact decimal number which can't be represented exactly in binary floating point, arguably 0.2 is a simpler example as it's 1/5 - and 5 is the prime that causes problems between decimal and binary. Some floating decimal point types have a fixed size like 这篇关于为什么十进制数不能完全用二进制表示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! System.Decimal
others像> java.math.BigDecimal
是任意大 - 但是它们会在某个时刻达到一个极限,无论是系统内存还是理论上的最大数组大小。然而,这与这个答案的主要部分完全是分开的。即使你有一个真正的大量的位来玩,你仍然不能精确地表示浮点二进制表示的十进制0.1。与其他方式比较:给定任意数量的小数位数,您可以 ... 1000 100 10 1 1/10 1/100 ...
... 8 4 2 1 1/2 1/4 1/8 ...
System.Decimal
in .NET) then plenty of values which can't be represented exactly in binary floating point can be exactly represented.
Side note to deal with the problem of finite representations:
System.Decimal
others like java.math.BigDecimal
are "arbitrarily large" - but they'll hit a limit at some point, whether it's system memory or the theoretical maximum size of an array. This is an entirely separate point to the main one of this answer, however. Even if you had a genuinely arbitrarily large number of bits to play with, you still couldn't represent decimal 0.1 exactly in a floating binary point representation. Compare that with the other way round: given an arbitrary number of decimal digits, you can exactly represent any number which is exactly representable as a floating binary point.