In Python, what is a good way to round towards zero in integer division?

旧街凉风 提交于 2019-11-27 02:38:44

问题


1/2

gives

0

as it should. However,

-1/2

gives

-1

, but I want it to round towards 0 (i.e. I want -1/2 to be 0), regardless of whether it's positive or negative. What is the best way to do that?


回答1:


Do floating point division then convert to an int. No extra modules needed.

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



回答2:


Python's default division of integers is return the floor (towards negative infinity) with no ability to change that. You can read the BDFL's reason why.

To do 'round up' division, you would use:

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

To do truncation towards zero, and maintain integer division, you use (a+(-a%b))//b if either a or b are negative and the default division if both are positive.

This will do integer division and always round towards zero:

>>> 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

footnote

Interestingly enough, C99 declares that round towards zero is the default:

#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;
}

Prints:

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



回答3:


For what it's worth, my own favourite solution is this one. Integer arithmetic only, a single division, and everything else linear time:

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

That assumes that b is positive, but in most of the applications I've seen that's true. If you need to deal with negative b too, then the function becomes marginally more complicated:

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

Some sample outputs:

>>> 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



回答4:


Try this. Only works for numbers greater than -1

import math

x = .5
y = -.5

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

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



回答5:


Correct code to do this is, in my opinion, too obscure to write as a 1-liner. So I'd put it in a function, like:

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

Good features: it works for any size of int, doesn't make any adjustment to the raw (a//b) result unless necessary, only does one division (% also does a division under the covers), and doesn't create any integers larger than the inputs. Those may or may not matter in your application; they become more important (for speed) if you use "big" integers.




回答6:


Throwing my hat in with a few alternate ideas:

Multiple the sign of the number [abs(x)/x] by the abs(x)/2

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

Perform the addition, but if the number is less than zero add one to shift it closer to 0.

x/2 + int(x<0)



回答7:


You can also use the Decimal module as part of the standard python libraries.

Specifically, " The integer division operator // behaves analogously, returning the integer part of the true quotient (truncating towards zero) rather than its floor, so as to preserve the usual identity x == (x // y) * y + x % y:"

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

Also, have a look at Rounding Modes as they've got quite a few ways to view/round your information - Ceiling, down, floor, half-down, half-even, half-up, up and 05up rounding.

Decimal was written as a solution to the traditional problem of binary mathematics in a world expecting decimals solutions




回答8:


why reinvent the wheel, when there's a perfectly good math.trunc() function?

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


来源:https://stackoverflow.com/questions/19919387/in-python-what-is-a-good-way-to-round-towards-zero-in-integer-division

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!