[英]Floating point representations seem to do integer arithmetic correctly - why?
我一直在玩浮點數,根據我過去對它們的了解, 0.1 + 0.2
最終變成0.30000000000000004
事實並不讓我感到驚訝。
是什么讓我感到吃驚,但是,是整數運算似乎總是工作得很好,並沒有這些文物。
我首先在JavaScript中注意到這一點(node.js中的Chrome V8):
0.1 + 0.2 == 0.3 // false, NOT surprising
123456789012 + 18 == 123456789030 // true
22334455667788 + 998877665544 == 23333333333332 // true
1048576 / 1024 == 1024 // true
C ++(Mac OS X上的gcc)似乎具有相同的屬性。
最終的結果似乎是整數,只是 - 缺乏一個更好的詞 - 工作 。 只有當我開始使用十進制數字時,事情變得不穩定。
這是設計的特征,數學工件,還是編譯器和運行時環境所做的一些優化?
這是設計的特征,數學工件,還是編譯器和運行時環境所做的一些優化?
這是實數的一個特征。 現代代數(現代代數,不是高中代數;數學專業在基本微積分和線性代數類之后在現代代數中取一類)的定理說,對於某些正整數b ,任何正實數r都可以表示為r = a * b p ,其中a在[1, b )中, p是某個整數。 例如,1024 10 = 1.024 10 * 10 3 。 正是這個定理證明了我們使用科學記數法是正確的。
該數字a可以被分類為終端(例如1.0),重復(1/3 = 0.333 ......)或非重復(pi的表示)。 這里有終端號碼的小問題。 任何終端號碼也可以表示為重復數字。 例如,0.999 ...和1是相同的數字。 可以通過指定可以表示為終端號的數字如此表示來解決表示中的這種模糊性。
您發現的是所有整數在任何基數中都具有終端表示的結果。
這里有一個關於如何在計算機中表示實數的問題。 就像int
和long long int
不代表所有整數一樣, float
和double
也不代表所有的實數。 在大多數計算機上用來表示實數r的方案是以r = a * 2 p的形式表示,但是尾數(或有效數) 被截斷為一定數量的位並且指數p限於某個有限數。 這意味着某些整數無法准確表示。 例如,即使googol(10 100 )是一個整數,它的浮點表示也不准確。 googol的基數2表示是333位數。 該333位尾數被截斷為52 + 1位。
這樣做的結果是雙精度算術不再精確,即使對於整數,如果所討論的整數大於2 53 。 在2 53和2 64之間的值上使用unsigned long long int
類型嘗試您的實驗。 您會發現對於這些大整數,雙精度算術不再精確。
我寫的是假設Javascript對所有數字使用雙精度浮點表示。
一些數字具有浮點格式的精確表示,特別是所有整數,如|x| < 2^53
|x| < 2^53
。 某些數字尤其不是諸如0.1或0.2的分數,其在二進制表示中變為無限分數。
如果所有操作數和操作結果都具有精確表示,那么使用==
比較結果是安全的。
相關問題:
具有可表示范圍的整數可由機器准確表示,浮點數不是(嗯,大多數)。
如果通過“基本整數數學”你理解“特征”,那么是的,你可以假設正確實現算術是一個特征。
原因是,您可以完全以二進制格式(0001,0010,0011,...)表示每個整數(1,2,3,...)
這就是為什么整數總是正確的,因為0011 - 0001總是為0010.浮點數的問題是,點之后的部分不能精確地轉換為二進制。
您說“工作”的所有情況都是您給出的數字可以用浮點格式精確表示的情況。 您會發現添加0.25和0.5以及0.125也可以正常工作,因為它們也可以精確地表示為二進制浮點數。
它只是不能達到0.1的值,你會得到看似不精確的結果。
整數是准確的,因為不精確的結果主要來自我們寫小數部分的方式,其次是因為許多有理數在任何給定的基數中都沒有非重復的表示。
有關完整說明,請參閱: https : //stackoverflow.com/a/9650037/140740 。
只有當你向一個非常大的整數添加一個足夠小的整數時,該方法才有效 - 即使在這種情況下,你也不能以“浮點”格式表示兩個整數。
無法表示所有浮點數。 這是由於編碼方式。 維基頁面比我更好地解釋了它: http : //en.wikipedia.org/wiki/IEEE_754-1985 。 因此,當您嘗試比較浮點數時,應使用delta:
myFloat - expectedFloat < delta
您可以使用最小的可表示浮點數作為delta。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.