我需要从C到Python移植相当多的公式,反之亦然。什么是确保在此过程中没有任何中断的最佳方法?
我希望我的问题听起来不太一般。我主要担心自动 int / int = float 转换。
答案 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通常不是正确的选择。 ;)