В Python, что является хорошим способом округления к нулю в целых делениях?

1/2

дает

0

как и следовало ожидать. Тем не менее,

-1/2

дает

-1

но я хочу, чтобы он округлился до 0 (т.е. я хочу, чтобы -1/2 было 0), независимо от того, является ли оно положительным или отрицательным. Каков наилучший способ сделать это?

Ответ 1

Деление с плавающей запятой затем преобразуется в int. Никаких дополнительных модулей не требуется.

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

Ответ 2

Деление целых чисел по умолчанию на Python возвращает пол (к отрицательной бесконечности) без возможности его изменения. Вы можете прочитать причину BDFL.

Чтобы выполнить разделение "round up", вы должны использовать:

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

Чтобы сделать усечение в направлении нуля и поддерживать целочисленное деление, вы используете (a+(-a%b))//b, если либо a, либо 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 to 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

Ответ 3

Для чего это стоит, мое собственное любимое решение - это одно. Целочисленная арифметика, единственное деление и все остальное линейное время:

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

Ответ 4

Попробуйте это. Работает только для чисел больше -1

import math

x = .5
y = -.5

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

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

Ответ 5

Правильный код для этого, на мой взгляд, слишком неясен, чтобы писать как 1-лайнер. Поэтому я бы поставил его в функцию, например:

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

Хорошие возможности: он работает для любого размера int, не корректирует исходный результат (a//b), если это необходимо, только одно подразделение (% также выполняет разделение под обложками) и не создает никаких целых чисел больше входных данных. Это может быть или не иметь значения в вашей заявке; они становятся более важными (для скорости), если вы используете "большие" целые числа.

Ответ 6

Бросив мою шляпу с несколькими альтернативными идеями:

Множество знака числа [abs (x)/x] на abs (x)/2

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

Выполните добавление, но если число меньше нуля, добавьте его, чтобы сместить его ближе к 0.

x/2 + int(x<0)

Ответ 7

Вы также можете использовать модуль Decimal как часть стандартных библиотек python.

В частности, "Оператор целочисленного деления//ведет себя аналогично, возвращая целую часть истинного частного (обрезая в сторону нуля), а не его пол, чтобы сохранить обычную идентификацию x == (x//y) * y + x% y:"

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

Кроме того, посмотрите Rounding Modes, поскольку у них есть несколько способов просмотра/округления информации - Потолок, вниз, пол, полузакрытый, полу-четный, половинный, вверх и округлый.

Десятичная была написана как решение традиционной проблемы бинарной математики в мире, ожидающем десятичных решений