Python 3整数除法。如何使数学运算符与C一致

时间:2011-03-19 23:32:29

标签: python-3.x

我需要从C到Python移植相当多的公式,反之亦然。什么是确保在此过程中没有任何中断的最佳方法?

我希望我的问题听起来不太一般。我主要担心自动 int / int = float 转换。

5 个答案:

答案 0 :(得分:31)

您可以使用//运算符,它执行整数除法,但它不是您对C的期望:

引自here

  

//运算符执行奇怪的整数除法。当。。。的时候   结果是积极的,你可以想到   它截断(不舍入)为0   小数位,但要小心   这一点。

     

当整数除以负数时,//运算符向上舍入“向上”   到最近的整数。数学   说起来,它正在向下“四舍五入”   -6小于-5,但它可能会跳闸   如果你期待的话,你   截断为-5。

例如,Python中的-11 // 2返回-6,其中C中的-11 / 2返回-5。 我建议编写并彻底单元测试一个“模拟”C行为的自定义整数除法函数。

我上面链接的页面还有一个指向PEP 238的链接,其中包含有关除法的一些有趣背景信息以及从Python 2到3的更改。有一些关于如何使用整数除法的建议,例如{{对于正数,1}}和divmod(x, y)[0],也许你会在那里找到更多有用的东西。

答案 1 :(得分:0)

在C中:

-11/2 = -5

在Python中:

-11/2 = -5.5

以及python中的

-11//2 = -6

要实现类似C的行为,请在python中编写int(-11/2),这将得出-5

答案 2 :(得分:0)

对不起,我的回答是相反的,但是我找不到这样的问题,所以无论如何:

由于Python3 divmod(或//)整数除法要求余数在非零余数情况下与除数具有相同的符号,因此它与许多其他语言(来自http://anh.cs.luc.edu/handsonPythonTutorial/integer.html的引用)不一致

要使“类似于C的”结果与Python相同,应将余数与除数进行比较(建议:对符号位进行xor等于1,或与负数相乘),如果不相同,则添加除以除数,然后从商中减去1

        // Python Divmod requires remainder with the same sign as Divisor for 
        // non-zero remainder

        // Assuming isPyCompatible is a flag to distinguish c/py mode
        isPyCompatible *= (int)remainder;
        if (isPyCompatible)
        {
            int32_t xorRes = remainder ^ divisor;
            int32_t andRes = xorRes & ((int32_t)((uint32_t)1<<31));
            if (andRes)
            {
                remainder += divisor;
                quotient -= 1;
            }
        }

(感谢Gawarkiewicz M.指出这一点)

答案 3 :(得分:0)

使用C语义计算整数除法的一些方法如下:

def div_c0(a, b):
    if (a >= 0) != (b >= 0) and a % b:
        return a // b + 1
    else:
        return a // b
def div_c1(a, b):
    q, r = a // b, a % b
    if (a >= 0) != (b >= 0) and a % b:
        return q + 1
    else:
        return q
def div_c2(a, b):
    q, r = divmod(a, b)
    if (a >= 0) != (b >= 0) and a % b:
        return q + 1
    else:
        return q
def mod_c(a, b):
    return (a % b if b >= 0 else a % -b) if a >= 0 else (-(-a % b) if b >= 0 else a % b)


def div_c3(a, b):
    r = mod_c(a, b)
    return (a - r) // b

有时间:

n = 100
l = [x for x in range(-n, n + 1)]
ll = [(a, b) for a, b in itertools.product(l, repeat=2) if b]


funcs = div_c0, div_c1, div_c2, div_c3
for func in funcs:
    correct = all(func(a, b) == funcs[0](a, b) for a, b in ll)
    print(func.__name__, 'correct:', correct)
    %timeit [func(a, b) for a, b in ll]
    print()
div_c0 correct: True
100 loops, best of 3: 8.42 ms per loop

div_c1 correct: True
100 loops, best of 3: 10 ms per loop

div_c2 correct: True
100 loops, best of 3: 12.3 ms per loop

div_c3 correct: True
100 loops, best of 3: 13.1 ms per loop

表明第一种方法是最快的。


有关使用Python实现C的%的信息,请参见here

答案 4 :(得分:-1)

您需要知道公式的作用,并了解C实现以及如何在Python中实现它。但除非你正在进行整数数学,否则它应该非常相似,如果 进行整数数学运算,问题就是原因。 :)

整数数学要么是因为某些特定目的而经常完成的,通常与计算机有关,要么因为它在进行大量计算时比浮点数快,比如Fractint对分形的影响,在这种情况下,Python通常不是正确的选择。 ;)