[英]How can I simulate GNU C Library drem / remainder function in Google App Engine Python 2.7 runtime?
GNU C庫具有函數drem
(別名remainder
)。
如何使用Google App Engine Python 2.7運行時支持的模塊來模擬此功能?
從drem
的GNU手冊 :
這些函數類似於
fmod
除了它們將內部商n舍入到最接近的整數而不是零到整數。 例如,drem(6.5,2.3)返回-0.4,即6.5減6.9。
從fmod
的GNU手冊 :
這些函數通過分母從分子的除法計算余數。 具體來說,返回值是分子 - n *分母,其中n是分子除以分母的商,向零四舍五入為整數。 因此,fmod(6.5,2.3)返回1.9,即6.5減去4.6。
閱讀文檔,以下Python代碼應該有效:
def drem(x, y):
n = round(x / y)
return x - n * y
但是對於Python, drem(1.0, 2.0) == -1.0
和C drem(1.0, 2.0) == 1.0
。 注意Python返回負數 ,C返回正數 。 這幾乎可以肯定是圓形浮子的內部差異。 據我所知,兩個函數執行相同的操作,否則參數2 * x != y
。
如何使我的Python drem
函數與其C等效函數相同?
解決這個問題的關鍵是要認識到drem
/ remainder
函數規范要求內部舍入計算舍入到一半。
因此,我們不能在Python 2.x中使用內置的round
函數,因為它從0開始舍入。然而,Python 3.x中的round
函數已經變為round to half even。 所以下面的Python 3.x代碼將等同於GNU C Library drem
函數,但在Python 2.x中不起作用 :
def drem(x, y):
n = round(x / y)
return x - n * y
為了實現與Python 2.x相同,我們可以使用decimal模塊及其remainder_near函數:
import decimal
def drem(x, y):
xd = decimal.Decimal(x)
yd = decimal.Decimal(y)
return float(xd.remainder_near(yd))
編輯:我剛看了你的第一條評論,看到你不能使用ctypes
模塊。 無論如何,我今天通過試圖找到問題的答案我學到了很多東西。
考慮到numpy.round()
四舍五入值與下一個偶數整數之間的值完全舍入,使用numpy不是一個好的解決方案。
此外, drem
內部調用此MONSTER函數 ,這在Python中很難實現。
受本文的啟發,我建議您直接從數學庫中調用drem
函數。 這些方面的東西應該可以解決問題:
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))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.