SORU
23 NİSAN 2012, PAZARTESİ


Yerleşik pow arasındaki fark() ve math.() pow Python yüzer için?

Var sonuçları Piton yılanı tarafından döndürülen dahili pow(x, y) (üçüncü argüman) ve değerleri söz konusu iki math.pow() tarafından döndürülen bir farkyüzerargümanlar.

math.pow() documentation pow(x, y) (yani x**y) aslında math.pow(x, y) ile aynı olduğunu ima eder, çünkü bu soruyu soruyorum:

matematik.pow(x, y)

X Güç y kaldırdı dönüş. İstisnai durumlar Ek ‘F’ C99 standardının mümkün olduğu kadar izleyin İçinde özellikle, pow(1.0, x) ve pow(x, 0.0) her zaman iade 1.0, hatta zaman x sıfır ya da bir NaN. Eğer her ikisi de x ve y sonlu ise x negatif, y bir tamsayı sonra pow(x, y) tanımlı değil, ve yükseltir ValueError.

Sürüm 2.6 değişti: 1**nan nan sonucu**0 tanımsız.

Not son satırı: belgeleri math.pow() davranış üs alma operatörü ** (pow(x, y) Bu nedenle) olduğunu ima eder. Bu resmi garantili mi?

Amaç: amacım bir uygulama sağlamaktırher ikisi deyerleşik pow() ve belirsizlik ile sayılar math.pow()o da aynı şekilde davranırdüzenli Python yüzer (sayısal sonuçlar, aynı durumlar, aynı sonuçlar aynı köşe durumlarda, vb.) olduğu gibi. already implemented çok iyi çalışan bir şey var, ama halledilmesi gereken corner cases bazı vardır.

CEVAP
23 NİSAN 2012, PAZARTESİ


Hızlı Onay

İmzalar, farklı olduklarını söyleyebiliriz:

(x, [z] y) pow

matematik.pow(x, y)

Ayrıca, kabuk içinde çalıştığını hızlı bir fikir verecektir:

>>> pow is math.pow
False

Farkın test edilmesi

İki işlev arasındaki davranış farklılıkları anlamak için başka bir yolu onları test etmektir:

import math
import traceback
import sys

inf = float("inf")
NaN = float("nan")

vals = [inf, NaN, 0.0, 1.0, 2.2, -1.0, -0.0, -2.2, -inf, 1, 0, 2]

tests = set([])

for vala in vals:
  for valb in vals:
    tests.add( (vala, valb) )
    tests.add( (valb, vala) )


for a,b in tests:
  print("math.pow(%f,%f)"%(a,b) )
  try:
    print("    %f "%math.pow(a,b))
  except:
    traceback.print_exc()

  print("__builtins__.pow(%f,%f)"%(a,b) )
  try:
    print("    %f "%__builtins__.pow(a,b))
  except:
    traceback.print_exc()

Sonra bazı ufak değişiklikler fark edebilirsiniz. Örneğin:

math.pow(0.000000,-2.200000)
    ValueError: math domain error

__builtins__.pow(0.000000,-2.200000)
    ZeroDivisionError: 0.0 cannot be raised to a negative power

Başka farklar ve test yukarıdaki liste tam değildir (uzun sayılar, karmaşık, vb...), ama bu bizim, bir pragmatik listesi nasıl iki işlev farklı şekilde davranır. Ayrıca her döndürür işlev türünü kontrol etmek için yukarıdaki test uzanan tavsiye ederim. Muhtemelen iki işlevi arasındaki farklılıkları bir rapor oluşturur benzer bir şey yazabilirsiniz.

math.pow()

math.pow() çok farklı değişkenleri yerleşik ** pow() işler. Bu esneklik pahasına geliyor. the source, biz de bir göz olan math.pow() bağımsız olduğunu görebilirsinizdoğrudan çift için döküm:

static PyObject *
math_pow(PyObject *self, PyObject *args)
{
    PyObject *ox, *oy;
    double r, x, y;
    int odd_y;

    if (! PyArg_UnpackTuple(args, "pow", 2, 2, &ox, &oy))
        return NULL;
    x = PyFloat_AsDouble(ox);
    y = PyFloat_AsDouble(oy);
/*...*/

Çekler daha sonra geçerliliğini çiftlerde uygulanıyor ve sonucu C temel matematik kütüphaneye geçti.

pow() yerleşik

Yerleşik pow() (aynı ** operatör) diğer yandan davranır çok farklı, aslında kullandığı Nesneleri kendi uygulama ** operatör, hangi tarafından geçersiz kılınabilir son kullanıcı eğer ihtiyaç tarafından yerine bir sayı __pow__(), __rpow__() __ipow__() yöntem.

Yerleşik türleri için, güç fonksiyonu iki sayısal türleri, örneğin, floats, long complex için uygulanan arasındaki farkı incelemek için öğreticidir.

Varsayılan davranış Overridding

Sayısal türler taklit açıklanmıştır here. yapmanız gereken ne olursa belirsizlik olan sayılar için yeni bir tür oluştururken, esas olarak, kendi türü için __pow__(), __rpow__() muhtemelen __ipow__() yöntem sağlar. Bu numaralar operatörü ile kullanılmak üzere izin verir:

class Uncertain:
  def __init__(self, x, delta=0):
    self.delta = delta
    self.x = x
  def __pow__(self, other):
    return Uncertain(
      self.x**other.x, 
      Uncertain._propagate_power(self, other)
    )
  @staticmethod
  def _propagate_power(A, B):
    return math.sqrt(
      ((B.x*(A.x**(B.x-1)))**2)*A.delta*A.delta  
      (((A.x**B.x)*math.log(B.x))**2)*B.delta*B.delta
    )

math.pow() geçersiz kılmak için yama maymun yeni tür destek için var

def new_pow(a,b):
    _a = Uncertain(a)
    _b = Uncertain(b)
    return _a ** _b

math.pow = new_pow

Bu iş için __init__() bir giriş olarak Uncertain örneği ile başa çıkmak için Uncertain sınıfı gelmeniz gerekecek unutmayın

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • FRED

    FRED

    1 EKİM 2005
  • InfoPuppet

    InfoPuppet

    15 Kasım 2011
  • Jesse Pimenta

    Jesse Piment

    5 EKİM 2011