2015-06-10 19 views
8

Programlama sırasında math.exp (2) ve math.e ** 2 sonuçları arasında fark olduğunu farkettim. Aşağıda görebileceğiniz gibi, e^1 hesaplanırken bu fark ortaya çıkmaz.math.exp (2) ve math.e ** arasındaki fark 2

Tecrübeli bir programcı olmamasından dolayı bunun neden farklı olduğunu merak ettim. Yuvarlama ile ilgili bir şey olduğunu varsayalım. Python docs, math.exp(x)'un e**x döndürdüğünü söylüyor, ancak bu tam olarak doğru değil gibi görünüyor. Peki, math.exp(x) işleminin math.e**x'dan farkı nedir?

>>> math.exp(1) 
2.718281828459045 
>>> math.e**1 
2.718281828459045 
>>> math.exp(1)==math.e**1 
True 
>>> math.exp(2) 
7.38905609893065 
>>> math.e**2 
7.3890560989306495 
>>> math.exp(2)==math.e**2 
False 
>>> math.exp(100) 
2.6881171418161356e+43 
>>> math.e**100 
2.6881171418161212e+43 
>>> math.exp(100)==math.e**100 
False 
+2

İlgili: http://stackoverflow.com/a/15322395/1639625 Tahminim: 'math.exp', c'de (veya hatta donanımda) uygulanır ve bu nedenle biraz farklı kayan nokta davranışı vardır. –

+1

Yeniden açılmak için oylama. Burada daha çok "kayan nokta yanlış" olmaktan daha fazlası var. Özellikle, iki cevap açıkladığı gibi, exp (x) 'inin e ** x'den daha doğru olmasını beklemek için iyi sebepler vardır. –

cevap

4

İşlevlerin uygulanmasındaki farklılıklar nedeniyle farklıdır. Kayan noktaların doğası nedeniyle ikisi de mükemmel değildir.

** işleci, floatobject.c'da uygulanır ve çok sayıda özel durum içerir, ancak bunların hiçbiri burada çağrılmaz, bu nedenle sonuçta standart C pow işlevine ulaşır. math.pow işlevi sonuçta aynı şeyi yapar.

exp işlevi, mathmodule.c numaralı belgede bir makro ile tanımlanan aynı adın C işlevi etrafında basit bir sarmalayıcıdır.

Olduğu gibi, exp daha hassastır (sonuçların her ikisi de, kayan nokta tarafından izin verilen hassasiyet dahilinde, bc cinsinden hesaplanan yüksek hassasiyetli yanıtlar). içten, o temel mesele olduğunu biraz daha küçük 1.


daha ilk argüman olarak geçmesi çift hassasiyetli e değerin genişletilmiş hassasiyet logaritma hesaplıyor pow çünkü öyle Büyük olasılıkla Eğer gücünü hesaplayarak ediyoruz sayıdır math.e, şöyledir:

2.718281828459045 09079559829... 

e gerçek değeri

2.718281828459045 23536028747... 
Oysa

Ve bu hata, pow veya ** kullanırken, exp kullandığı algoritmaların ayrıntılarından dolayı kullanmıyor olabilir (veya daha yüksek hassasiyetli bir değer kullanıyor olabilir).

+0

Anlayışım için: bc nedir? – oscarwhiskybravo

+0

@ rosie2go Rasgele hassas bir komut satırı hesaplayıcısı olan unix ve linux sistemleri için - bu keyfi bir hassaslık olarak 50 rakamı hesaplamak ve bu sonucu python float sonucuyla karşılaştırmak için ayarlayabilirsiniz. – Random832

+0

Yani, bir tam sayı olarak değiştirdiğinizde, tam sayı 1, 0,999999999999999999468198834395860075119344401173293590545654296875 olur? – oscarwhiskybravo

5

exp(x)e**x çok daha düşük seviyede uygulanmaktadır. Aslında libc'de bir işlev için bir sarmalayıcıdır. Bu fonksiyon muhtemelen (bir düzeyde) Taylor series genişlemesini kullanarak değeri doğrudan hesaplamaktır (veya muhtemelen başka bir matematiksel yöntem, emin değilim).

Diğer yandan, e**x bir numara alıyor ve bir güce yükseltiyor. Bu tamamen farklı bir stratejidir ve çoğu durumda muhtemelen daha az hassastır. Sayıları yetkilere yükseltmek tam olarak zor.