2016-10-01 46 views
13

Python 2.7 ve 3.x'da, tamsayı bölümü 0 < x < 1 numaralı bir numaraya bölünürken neden doğru olmayan bir sayı verir?Neden 1 // 0.1 == 9.0?

Negatif sayılar -1 < x < 0 bile düzgün çalışması:

>>> 1//.1 
9.0 
>>> 1//-.1 
-10.0 

ancak ben 1 olabilir çünkü 1//.110.0 yol açmalıdır aklına gelirdi, bir negatif (veya pozitif) sayı negatif sonsuzluğa doğru yuvarlar o tamsayı bölme anlıyorum Kalan olmadan .1 bölünür.

+4

Zemin bölümü. Bu gönderiye bakın: http://stackoverflow.com/questions/5535206/negative-integer-division-surprising-result – Manhattan

+3

kat (1/.1), –

+6

muhtemelen başka bir artifact olsa da 10'a eşit olmalıdır. ?] (http://stackoverflow.com/questions/588004/is-floating-point-math-broken) –

cevap

26

Burada gördüğünüz şey, temel olarak / ve // numaralı döşeme bölümü kullanılarak “normal” bölüm arasındaki farkın etkisidir.

Akılda tutulması gereken her zaman önemli olan, bunların nasıl çalıştığından dolayı belirli bir mahsur olan general issue with floating point arithmetic. Bu durumlarda, aslında neler olup bittiğini kontrol etmek için decimal modülünü kullanmak her zaman iyidir. Burada ne yaptığını Yani en bakalım: Her şeyden

Öncelikle .1 zaten kesin değildir:

>>> Decimal(1)/Decimal(.1) 
Decimal('9.999999999999999444888487687') 
>>> 1/.1 
10.0 

:

>>> Decimal(.1) 
Decimal('0.1000000000000000055511151231257827021181583404541015625') 

Yani, bölünmeler fiili sonucu bakalım Gördüğünüz gibi, /'u kullanarak normal bölümleme, tam olarak 10 kayan nokta aritmetiği vermez. Ama gerçekten yakın. İşte bu yüzden, normal floatlar kullandığınızda, aslında 10'a geri dönersiniz (çünkü bölümün hatasızlığı sayı türünün hatasızlığında hemen kaybolur). negatif sayılar ile

>>> Decimal(1) // Decimal(.1) 
Decimal('9') 
>>> 1/.1 
10.0 

, döşeme etkisi ters yönde olduğu in that other question açıklandığı gibi: döşeme bölümü kullanırken 9 olsun yüzden bu yüzden

, sonuç, belirsizlik düzeltilir önce çekilir :

>>> Decimal(1)/Decimal(-.1) 
Decimal('-9.999999999999999444888487687') 
>>> 1/-.1 
-10.0 
>>> Decimal(1) // Decimal(-.1) 
Decimal('-9') 
>>> 1 // -.1 
-10.0 
+3

Başka bir iyi örnek, '-11.0' ile sonuçlanan negatif bir sayı ile" ** başarısız "** olduğu' 3 // -.3'. –

+0

note: 'Ondalık (" 1 ") // Ondalık (" 0.1 ")' Ondalık sayıları tam olarak gösterebildiğinden Decimal ("10") 'verir. Ondalık, verilen sayıları tam olarak korur, böylece ondalık bir dize vermek, insan girdisi için daha hassas olabilir –

İlgili konular