2011-07-14 13 views
2

所以我有兩個浮動元組的列表每個。每個元組代表一個範圍。我正在通過另一個浮點數列表來表示適合範圍的值。所有這些花車都是< 1,但是積極的,所以精確的問題。我的一個測試,以確定一個值是否適合一個範圍是失敗,當它通過。如果我打印的價值,並引起問題的範圍內,我可以多說的:浮動內部元組訪問時更改值

curValue = 0.00145000000671 
range = (0.0014500000067055225, 0.0020968749796738849) 

發生故障的條件是:

if curValue > range[0] and ... blah : 
    # do some stuff 

由curValue和範圍,測試給出的值應該明確地通過(不要擔心有條件的內容)。現在,如果我明確地打印範圍[0]的值是什麼,我得到:

range[0] = 0.00145000000671 

這將解釋爲什麼測試失敗。所以我的問題是,爲什麼浮點數在訪問時會發生變化。當元組的一部分存在時,它具有達到一定精確度的十進制值,並且在訪問時具有不同的精度。爲什麼會這樣?我能做些什麼來確保我的數據在我的計算中保持一致的精度?

+0

確定'0.00145000000671'或'0.0014500000067055225'可以完全按照您的預期表示? –

+0

@Graham你能提供一個5行示例程序來展示問題嗎?如果沒有,問題可能出現在你的代碼中;) – phihag

+0

curValue> range [0]在我的機器上返回True ...條件我們不應該擔心看起來像你的問題......或者它實際上是在做「東西「,你只是沒有意識到它 – Gerrat

回答

3

浮動不會改變。內置的數字類型都是不可變的。爲您看到的是什麼樣的原因是:

  1. print range[0]上浮動,這(直到非常最新版本的Python)印刷少了浮動的數字使用str
  2. 打印一個元組(使用reprstr)對各個項目使用repr,這給出了更精確的表示(再次,在最近的版本中,對於兩者都使用更好的算法,這不再是真實的)。

至於爲什麼這種情況不能按照您的預期行事,它可能是通常的罪魁禍首,浮動的精度有限。嘗試print repr(curVal), repr(range[0])以查看Python決定的是否是您的浮點文字最接近的表示。

+0

這是幫助我找到問題的答案。事實證明,即使我認爲curValue更大,curValue和range [0]實際上是相等的。 – Graham

3

在現代PC的彩車是不是準確。所以即使你輸入pi爲一個常數到100位小數,它只能得到一些準確的。你也一樣。這是因爲在32位浮點數中,你只能得到24位尾數,這限制了你的精度(並且以意想不到的方式,因爲它在base2中)。

請注意,0.00145000000671是不準確的值作爲存儲被Python。如果您使用print,則Python僅顯示完整存儲的浮點數的小數點。如果你想看看python如何存儲float,使用repr

如果你想更好的精度使用decimal模塊。

+1

請注意,小數點仍然是浮點數,仍然有限制(儘管默認和可調整大得多)的精度,但它與我們使用的基準10而不是基準2相同的不準確性。 – delnan

+0

Python的浮點數是C的兩倍,所以它不是32位浮點數,但關於有限精度的評論仍然適用。 – MRAB

+0

@delnan,python十進制模塊不會有這樣的不準確性,它不是基於 –

0

它不改變本身。 Python正在盡最大努力將數據存儲爲一個float數據,但是這個數字對於float來說太精確了,所以Python在它被訪問之前(在存儲它的過程中)修改它。有趣的是,這麼小的事情是如此巨大的痛苦。

你需要使用任意定點模塊像Simple Python Fixed Pointdecimal模塊。

0

不知道它會在這種情況下工作,因爲我不知道Python的輸出或存儲本身的限制,但你可以嘗試這樣做:

if curValue - range[0] > 0 and...