Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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

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

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

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

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.

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)

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top