簡體   English   中英

如何在Google App Engine Python 2.7運行時中模擬GNU C Library drem / remainder函數?

[英]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運行時支持的模塊來模擬此功能?

dremGNU手冊

這些函數類似於fmod除了它們將內部商n舍入到最接近的整數而不是零到整數。 例如,drem(6.5,2.3)返回-0.4,即6.5減6.9。

fmodGNU手冊

這些函數通過分母從分子的除法計算余數。 具體來說,返回值是分子 - 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM