2013-07-03 17 views
5

GNU C Kitaplığı drem (diğer adıyla remainder) işlevine sahiptir.Google App Engine Python 2.7 çalışma zamanında GNU C Kütüphanesi drem/remainder işlevini nasıl taklit edebilirim?

Bu işlevi, yalnızca Google App Engine Python 2.7 çalışma zamanı tarafından desteklenen modules kullanarak nasıl simüle edebilirim? drem için GNU manual itibaren

:

Bu işlevler onlar tam sayıya en yakın tam sayıya yerine sıfıra doğru iç bölüm n yuvarlamak dışında fmod gibidir. Örneğin, drem (6.5, 2.3), 6.5 eksi 6.9 olan -0.4'ü döndürür. fmod için GNU manual kaynaktan

:

Bu işlevler payda ile pay bölünmesinden kalan hesaplamak. Spesifik olarak, dönüş değeri pay-n * paydasıdır, burada n payda tarafından paylaştırılmış payın bölücüsüdür, bir tamsayıya sıfıra yuvarlanır. Böylece, fmod (6.5, 2.3), 6.5 eksi 4.6 olan 1,9 değerini döndürür.

Aşağıdaki Python kodu çalışmalıdır belgeleri Okuma:

def drem(x, y): 
    n = round(x/y) 
    return x - n * y 

Ancak Python, drem(1.0, 2.0) == -1.0 ile ve C drem(1.0, 2.0) == 1.0 ile. Not Python negatif bir döndürür ve C pozitif bir döndürür. Bu neredeyse yuvarlak yuvarlamalarda içsel bir farktır. Her iki işlev de, 2 * x != y parametrelerinin nerede olduğunu aynı şekilde söyleyebildiğim kadarıyla.

Python drem işlevimin C eşdeğeriyle aynı şekilde çalışmasını nasıl sağlayabilirim?

+0

Ben sadece kullanabileceğiniz eklemek gerekir Google App Engine mevcut (https://developers.google.com/appengine/kb/libraries) [Python modülleri desteklenen]. – Dan

+0

'numpy.round()' yerine 'round() 'örneğim için çalışıyor gibi görünüyor, ancak bununla ilgili herhangi bir kenar durumu olup olmadığını bilmek minnettar olurdum. – Dan

+0

** Sadece "yuvarlak" işlevi için Numpy'ye bağımlı olmamayı ** isterim ki soru hala geçerli olur. – Dan

cevap

5

bu sorunu çözmek için anahtar drem/remainderfunction specification bile yarısına tura iç yuvarlama hesaplama gerektirir fark etmektir.

nedenle kullanamazsınız yerleşik Python 2.x round fonksiyonu Python 3.x round fonksiyon bile yarısına tura değişti Ancak 0'a uzak yuvarlar olarak. Yani aşağıdaki Python 3.x kod Oylum drem işlevine eşit olacaktır ama Python 2.x çalışmaz:

def drem(x, y): 
    n = round(x/y) 
    return x - n * y 

biz ondalık modülü ve remainder_near işlevini kullanabilirsiniz Python 2.x ile aynı başarmak için :

import decimal 

def drem(x, y): 
    xd = decimal.Decimal(x) 
    yd = decimal.Decimal(y) 

    return float(xd.remainder_near(yd)) 
1

DÜZENLEME: Sadece ilk yorumunuzu okudum ve ctypes modülünü kullanamayacağınızı görüyorum. Her neyse, bugün senin problemine bir cevap bulmaya çalışarak çok şey öğrendim.

numpy.round()'un yuvarlatılmış ondalık değerler arasındaki tam olarak yarısı değerleri next even integer'a göre dikkate alındığında, numpy kullanımı iyi bir çözüm değildir. Ayrıca, drem, Python'da uygulanması zor olan bu MONSTER function numaralı telefonu dahili olarak adlandırır.

this article'dan ilham alarak, doğrudan matematik kitaplığından drem işlevini çağırmanızı öneririz. Bu doğrultuda bir şey hile yapmak gerekir:

from ctypes import CDLL 
# Use the C math library directly from Python 
# This works for Linux, but the version might differ for some systems 
libm = CDLL('libm.so.6') 

# For Windows, try this instead: 
# from ctypes import cdll 
# libm = cdll.libc 

# Make sure the return value is handled as double instead of the default int 
libm.drem.restype = c_double 
# Make sure the arguments are double by putting them inside c_double() 
# Call your function and have fun! 
print libm.drem(c_double(1.0), c_double(2.0)) 
+0

Soruşturma için çok teşekkür ederim ve 'numpy.round' dosyasının geçerli olmadığını bildirdiğiniz için teşekkür ederiz. Drem içsel fonksiyonun canavar olduğunu ve limana girmeye bile kalkmayacağımı kabul ediyorum! Soruyu güncelledik, böylece sadece App Engine çalışma zamanı modüllerini kullanmak daha belirgindir. App Engine çalışma zamanının sınırlamaları, yalnızca soruyu yazdıktan sonra ve tam olarak yukarıda önerdiğiniz şeyleri aynen yazarak yapmaya çalıştığımda gerçekleşti. – Dan