有几个关于浮点表示法的问题被提交给了SO。例如,十进制数0.1没有精确的二进制表示,因此使用==操作符将其与另一个浮点数进行比较是危险的。我理解浮点表示法背后的原理。
我不明白的是,为什么从数学的角度来看,小数点右边的数字比左边的数字更“特殊”?
例如,数字61.0具有精确的二进制表示,因为任何数字的整数部分总是精确的。但6.10这个数字并不准确。我所做的只是把小数点移了一位突然间我就从精确乌托邦变成了不精确镇。从数学上讲,这两个数字之间不应该有本质差别——它们只是数字。
相比之下,如果我把小数点向另一个方向移动一位,得到数字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 ...
这些数字也没有任意的限制。位置向左和向右无限增加。
这是个好问题。
你所有的问题都是基于“我们如何表示一个数字?”
所有的数字都可以用十进制表示,也可以用二进制(2的补码)表示。所有人!!
但有些(大多数)需要无穷多个元素(二进制位置为“0”或“1”,十进制表示为“0”,“1”到“9”)。
比如十进制表示的1/3(1/3 = 0.3333333…<-包含无限个“3”)
比如二进制中的0.1 (0.1 = 0.00011001100110011....<-带有无限个“0011”)
一切都在这个概念中。由于您的计算机只能考虑有限的数字集(十进制或二进制),只有一些数字可以准确地表示在您的计算机…
乔恩说过,3是质数,不是10的因数,所以1/3不能用以10为底的有限个数来表示。
即使使用任意精度的算术,以2为基数的编号位置系统也不能完全描述6.1,尽管它可以表示61。
对于6.1,我们必须使用另一种表示法(比如十进制表示法,或者允许以2为底或以10为底表示浮点值的IEEE 854)。
上面的高分答案完全正确。
首先,你的问题中混合了以2为底和以10为底的数,然后当你把一个不能整除的数放在右边时,你就有问题了。比如十进制的1/3因为3不能整除10的幂,或者二进制的1/5不能整除2的幂。
Another comment though NEVER use equal with floating point numbers, period. Even if it is an exact representation there are some numbers in some floating point systems that can be accurately represented in more than one way (IEEE is bad about this, it is a horrible floating point spec to start with, so expect headaches). No different here 1/3 is not EQUAL to the number on your calculator 0.3333333, no matter how many 3's there are to the right of the decimal point. It is or can be close enough but is not equal. so you would expect something like 2*1/3 to not equal 2/3 depending on the rounding. Never use equal with floating point.
在等式中
2^x = y ;
x = log(y) / log(2)
因此,我想知道我们是否可以有一个二进制的对数制,
2^1, 2^0, 2^(log(1/2) / log(2)), 2^(log(1/4) / log(2)), 2^(log(1/8) / log(2)),2^(log(1/16) / log(2)) ........
这也许能解决问题,所以如果你想把32.41写成二进制,那就是
2^5 + 2^(log(0.4) / log(2)) + 2^(log(0.01) / log(2))
Or
2^5 + 2^(log(0.41) / log(2))
根(数学)原因是,当你处理整数时,它们是可数无限的。
这意味着,即使它们的数量是无限的,我们也可以“数出”序列中的所有项目,而不会跳过任何一项。这意味着,如果我们想要在列表中的第610000000000000th位置上得到一项,我们可以通过一个公式来计算它。
然而,实数是无限的。你不能说“给我位置610000000000000的真实数字”并得到一个答案。原因是,即使在0到1之间,当考虑浮点值时,也有无限个值。这同样适用于任何两个浮点数。
更多信息:
http://en.wikipedia.org/wiki/Countable_set
http://en.wikipedia.org/wiki/Uncountable_set
更新:
很抱歉,我似乎误解了这个问题。我的回答是关于为什么我们不能表示每一个真实的值,我没有意识到浮点数被自动归类为理性。
你不能用二进制精确地表示0.1,就像你不能用传统的英国尺测量0.1英寸一样。
英国的尺子,就像二进制分数一样,都是关于一半的。你可以测量半英寸,或四分之一英寸(当然是一半),或八分之一,或十六分之一,等等。
If you want to measure a tenth of an inch, though, you're out of luck. It's less than an eighth of an inch, but more than a sixteenth. If you try to get more exact, you find that it's a little more than 3/32, but a little less than 7/64. I've never seen an actual ruler that had gradations finer than 64ths, but if you do the math, you'll find that 1/10 is less than 13/128, and it's more than 25/256, and it's more than 51/512. You can keep going finer and finer, to 1024ths and 2048ths and 4096ths and 8192nds, but you will never find an exact marking, even on an infinitely-fine base-2 ruler, that exactly corresponds to 1/10, or 0.1.
不过,你会发现一些有趣的事情。让我们看看我列出的所有近似值,对于每一个近似值,明确地记录0.1是大是小:
fraction |
decimal |
0.1 is... |
as 0/1 |
1/2 |
0.5 |
less |
0 |
1/4 |
0.25 |
less |
0 |
1/8 |
0.125 |
less |
0 |
1/16 |
0.0625 |
greater |
1 |
3/32 |
0.09375 |
greater |
1 |
7/64 |
0.109375 |
less |
0 |
13/128 |
0.1015625 |
less |
0 |
25/256 |
0.09765625 |
greater |
1 |
51/512 |
0.099609375 |
greater |
1 |
103/1024 |
0.1005859375 |
less |
0 |
205/2048 |
0.10009765625 |
less |
0 |
409/4096 |
0.099853515625 |
greater |
1 |
819/8192 |
0.0999755859375 |
greater |
1 |
现在,如果向下读最后一列,就会得到0001100110011。1/10的无限重复二进制分数是0.0001100110011,这不是巧合……