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

问题描述 投票:0回答:9
1/2

给予

0

理应如此。然而,

-1/2

给予

-1

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

python rounding division negative-number integer-division
9个回答
74
投票

进行浮点除法,然后转换为 int。不需要额外的模块。

Python 3:

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

Python 2:

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

11
投票

Python 的默认整数除法是返回下限(朝向负无穷大),并且无法更改它。您可以阅读 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 声明 向零舍入 是默认值:

#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

9
投票

就其价值而言,我自己最喜欢的解决方案就是这个。仅整数算术、单次除法和其他所有线性时间:

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

6
投票

既然有一个完美的 math.trunc() 函数,为什么还要重新发明轮子呢?

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

1
投票

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

import math

x = .5
y = -.5

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

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

1
投票

在我看来,执行此操作的正确代码太晦涩难懂,无法编写为 1-liner。所以我把它放在一个函数中,比如:

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

良好的功能:它适用于任何大小的 int,除非必要,否则不会对原始(

a//b
)结果进行任何调整,仅进行一次除法(
%
也在幕后进行除法),并且不' t 创建大于输入的任何整数。这些在您的申请中可能重要,也可能不重要;如果您使用“大”整数,它们会变得更加重要(对于速度)。


1
投票

提出一些替代想法:

将数字 [abs(x)/x] 的符号乘以 abs(x)/2

(abs(x)/x)*(abs(x)/2)

执行加法,但如果数字小于零,则加一以使其更接近 0。

x/2 + int(x<0)

1
投票

您还可以使用 Decimal 模块作为标准 Python 库的一部分。

具体来说, " 整数除法运算符 // 的行为类似,返回真商的整数部分(截断为零)而不是其下限,以便保留通常的恒等式 x == (x // y) * y + x % y :“

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

此外,请查看舍入模式,因为它们有多种方法来查看/舍入您的信息 - 向上舍入、向下舍入、向下舍入、向下舍入、半偶数舍入、向上舍入、向上舍入和 05 向上舍入。

十进制是作为二进制数学传统问题的解决方案而编写的,在这个世界上期待十进制解决方案


0
投票

你可以这样做:

import math

a=12
b=-11
result=math.trunc(a/b)

如果您使用 a//b,结果将为 0 而不是 -1 这样它总是将结果舍入到 0

© www.soinside.com 2019 - 2024. All rights reserved.