很簡單的問題困惑,但我真的很困惑:P第一天盧阿 - 通過一個循環
> for x = 0, 5, 0.2 do
print (x)
end
這個循環只計算至4.8 (一步法多與0.2會導致整整5,止跌「T嗎?)
但下面的for循環計數5
> for x = 0, 5, 1 do
print (x)
end
有人能解釋或參閱手冊,這些輸出背後的原因。也許我應該將變量定義爲float?
很簡單的問題困惑,但我真的很困惑:P第一天盧阿 - 通過一個循環
> for x = 0, 5, 0.2 do
print (x)
end
這個循環只計算至4.8 (一步法多與0.2會導致整整5,止跌「T嗎?)
但下面的for循環計數5
> for x = 0, 5, 1 do
print (x)
end
有人能解釋或參閱手冊,這些輸出背後的原因。也許我應該將變量定義爲float?
像往常一樣,當使用任何語言的浮動/雙打併且發生一些奇怪的事情時,搜索浮動/雙打如何以特定語言存儲。
這是已經回答here
作爲@jbr已經指出的,0.2被存儲爲0.2000000000000000111022302462515654042363166809082031250000000000
,當一個for循環運行時,它會檢查是否該值小於或等於5,並且由於該總和這些雙打比5大一點,它不會將其解釋爲此循環的成員,並立即退出。
你在這裏打的是很多人在Lua中感到困惑。在Lua中所有的數字都是雙打,這意味着並不是所有的數字有一個精確表示,0.2
是這些數字中的一個:
> print(string.format("%1.64f",math.abs(0.2)))
0.2000000000000000111022302462515654042363166809082031250000000000
所以你在這裏買到的積累錯誤。
如果您嘗試0.25
:
> print(string.format("%1.64f",math.abs(0.25)))
0.2500000000000000000000000000000000000000000000000000000000000000
所以
for x = 0, 5, 0.25 do
print(x)
end
按預期工作,爲更多的信息,請參閱Lua fails to evaluate math.abs(29.7 - 30) <= 0.3
for x = 0, 5, 0.2 do print (x) end
這個數字for
循環將步驟0.2
添加到初始值0
,執行處理(print(x)
),直到值爲<=5
。問題是,對於浮點數,0.2
無法精確表示,因此有一點四捨五入。所以當你認爲它應該總和爲5
時,它可能會更大一點。
對於不是很大的整數,它可以用雙精度浮點數精確表示,所以這沒有問題。
爲了您學習的Lua,稍尖的第一天:
double
。見下面*
:這不再是真實的。 Lua 5.3爲數字引入了一個新的整數子類型。請參見Changes in the Language
Lua通常代表ieee754binary64格式中的數字(「通常」,因爲表示實際上取決於基礎C實現)。二進制64中的closest number至0.2
是0x3FC999999999999A
或約0.200000000000000011102230246252
。
在源代碼中的0.2
計算髮生之前四捨五入到這個數字。
由於0.200000000000000011102230246252
比2
較大,數量中的最後一步變得大於5
,和因此該循環在約4.8
結束。
有關浮點數的詳細但溫和的解釋,請參見[每位計算機科學家應瞭解的浮點算術知識](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg。 HTML)由大衛戈德堡。 –
_Lua只有一個號碼類型,即由雙DEFAULT_ - 這就是說,加入整數支持是計劃在即將到來的[5.3的Lua(http://www.lua.org/work/的主要特徵之一doc /#changes)發佈。 – ComicSansMS
@ComicSansMS很高興知道。我會記得回到這裏,並在Lua 5.3發佈時修改答案:) –
@ComicSansMS,只要它比他們喜歡在嵌入式端口上隱藏的* horid *「Lua Number」補丁更好。 _ * shudders * _,它試圖將數字強制爲一對隱藏類型之一,並且它並不總是有效,產生bizzare錯誤消息。 – Textmode