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

前端 未结 8 1659
隐瞒了意图╮
隐瞒了意图╮ 2020-12-09 09:45
1/2

gives

0

as it should. However,

-1/2

gives

-1
相关标签:
8条回答
  • 2020-12-09 10:05

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

    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
    
    0 讨论(0)
  • 2020-12-09 10:07

    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
    
    0 讨论(0)
  • 2020-12-09 10:07

    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
    
    0 讨论(0)
  • 2020-12-09 10:17

    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

    0 讨论(0)
  • 2020-12-09 10:20

    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
    
    0 讨论(0)
  • 2020-12-09 10:20

    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)
    
    0 讨论(0)
提交回复
热议问题