在Python中,在整数除法中向零舍入的好方法是什么?

时间:2013-11-12 01:41:40

标签: python rounding division negative-number integer-division

1/2

给出

0

应该如此。然而,

-1/2

给出

-1

,但我希望它向0舍入(即我希望-1/2为0),无论它是正还是负。最好的方法是什么?

8 个答案:

答案 0 :(得分:13)

浮点除法然后转换为int。无需额外的模块。

>>> int(float(-1)/2)
0
>>> int(float(-3)/2)
-1
>>> int(float(1)/2)
0
>>> int(float(3)/2)
1

答案 1 :(得分:5)

Python的默认整数除法返回底线(朝向负无穷大),无法改变它。您可以read了解BDFL的原因。

要进行'向上'划分,您可以使用:

>>> a=1
>>> b=2
>>> (a+(-a%b))//b
1
>>> a,b=-1,2
>>> (a+(-a%b))//b
0

要向零截断并保持整数除法,如果a或b为负数,则使用(a+(-a%b))//b;如果两者均为正数,则使用默认除法。

这将进行整数除法并始终向零舍入:

>>> a=1
>>> b=2
>>> a//b if a*b>0 else (a+(-a%b))//b
0
>>> a=-1
>>> b=2
>>> a//b if a*b>0 else (a+(-a%b))//b
0
>>> a,b=-3,2
>>> a//b if a*b>0 else (a+(-a%b))//b
-1
>>> a,b=3,2
>>> a//b if a*b>0 else (a+(-a%b))//b
1

脚注

有趣的是,C99声明round towards zero是默认值:

#include <stdio.h>
int main(int argc, const char * argv[])
{

    int a=-3;
    int b=2;
    printf("a=%d, b=%d, a/b=%d\n",a,b,a/b);
    a=3;
    printf("a=%d, b=%d, a/b=%d\n",a,b,a/b);
    return 0;
}

打印:

a=-3, b=2, a/b=-1
a=3, b=2, a/b=1

答案 2 :(得分:4)

对于它的价值,我自己最喜欢的解决方案就是这个。仅整数算术,单个除法,以及其他所有线性时间:

def integer_divide_towards_zero(a, b):
    return -(-a // b) if a < 0 else a // b

假设b是正面的,但在大多数应用程序中我都看到了这一点。如果您还需要处理否定b,那么该函数会变得稍微复杂一些:

def integer_divide_towards_zero(a, b):
    return -(-a // b) if (a < 0) ^ (b < 0) else a // b

一些示例输出:

>>> integer_divide_towards_zero(11, 3)
3
>>> integer_divide_towards_zero(-11, 3)
-3
>>> integer_divide_towards_zero(6, 3)
2
>>> integer_divide_towards_zero(-6, 3)
-2
>>> integer_divide_towards_zero(11, -3)
-3
>>> integer_divide_towards_zero(-11, -3)
3

答案 3 :(得分:1)

试试这个。仅适用于大于-1的数字

import math

x = .5
y = -.5

print math.floor(math.fabs(x))
>> 0

print math.floor(math.fabs(y))
>> 0

答案 4 :(得分:1)

在我看来,正确的代码执行此操作太难以写成1行代码。所以我把它放在一个函数中,比如:

def int0div(a, b):
    q = a // b
    if q < 0 and b*q != a:
        q += 1
    return q

好的功能:它适用于任何大小的int,除非必要,否则不会对原始(a//b)结果进行任何调整,只有一个分区(%也会在cover),并且不会创建任何大于输入的整数。在您的申请中可能会或可能不重要;如果你使用“大”整数,它们会变得更加重要(速度)。

答案 5 :(得分:1)

用一些其他的想法投入我的帽子:

用abs(x)/ 2

表示数字[abs(x)/ x]的符号
(abs(x)/x)*(abs(x)/2)

执行添加,但如果数字小于零,则添加一个以将其移近0。

x/2 + int(x<0)

答案 6 :(得分:1)

您还可以将Decimal模块用作标准python库的一部分。

具体而言, “整数除法运算符//表现类似,返回真商的整数部分(截断为零)而不是其底限,以便保留通常的标识x ==(x // y)* y + x%y :“

>>> -7 // 4
-2
>>> Decimal(-7) // Decimal(4)
Decimal('-1')

此外,请查看Rounding Modes,因为他们有很多方法可以查看/查看您的信息 - 天花板,地板,地板,半场,半场,半场,上升和05up四舍五入。

在一个期望小数位解决方案的世界中,Decimal被写为传统二进制数学问题的解决方案

答案 7 :(得分:0)

当有一个非常好的math.trunc()函数时,为什么要重新发明轮子呢?

import math
print(math.trunc(-3.5))
>>-3
print(math.trunc(3.5))
>>3