Ответ 1
Деление с плавающей запятой затем преобразуется в int. Никаких дополнительных модулей не требуется.
>>> int(float(-1)/2)
0
>>> int(float(-3)/2)
-1
>>> int(float(1)/2)
0
>>> int(float(3)/2)
1
1/2
дает
0
как и следовало ожидать. Тем не менее,
-1/2
дает
-1
но я хочу, чтобы он округлился до 0 (т.е. я хочу, чтобы -1/2 было 0), независимо от того, является ли оно положительным или отрицательным. Каков наилучший способ сделать это?
Деление с плавающей запятой затем преобразуется в int. Никаких дополнительных модулей не требуется.
>>> int(float(-1)/2)
0
>>> int(float(-3)/2)
-1
>>> int(float(1)/2)
0
>>> int(float(3)/2)
1
Деление целых чисел по умолчанию на 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
Для чего это стоит, мое собственное любимое решение - это одно. Целочисленная арифметика, единственное деление и все остальное линейное время:
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
Попробуйте это. Работает только для чисел больше -1
import math
x = .5
y = -.5
print math.floor(math.fabs(x))
>> 0
print math.floor(math.fabs(y))
>> 0
Правильный код для этого, на мой взгляд, слишком неясен, чтобы писать как 1-лайнер. Поэтому я бы поставил его в функцию, например:
def int0div(a, b):
q = a // b
if q < 0 and b*q != a:
q += 1
return q
Хорошие возможности: он работает для любого размера int, не корректирует исходный результат (a//b
), если это необходимо, только одно подразделение (%
также выполняет разделение под обложками) и не создает никаких целых чисел больше входных данных. Это может быть или не иметь значения в вашей заявке; они становятся более важными (для скорости), если вы используете "большие" целые числа.
Бросив мою шляпу с несколькими альтернативными идеями:
Множество знака числа [abs (x)/x] на abs (x)/2
(abs(x)/x)*(abs(x)/2)
Выполните добавление, но если число меньше нуля, добавьте его, чтобы сместить его ближе к 0.
x/2 + int(x<0)
Вы также можете использовать модуль Decimal как часть стандартных библиотек python.
В частности, "Оператор целочисленного деления//ведет себя аналогично, возвращая целую часть истинного частного (обрезая в сторону нуля), а не его пол, чтобы сохранить обычную идентификацию x == (x//y) * y + x% y:"
>>> -7 // 4
-2
>>> Decimal(-7) // Decimal(4)
Decimal('-1')
Кроме того, посмотрите Rounding Modes, поскольку у них есть несколько способов просмотра/округления информации - Потолок, вниз, пол, полузакрытый, полу-четный, половинный, вверх и округлый.
Десятичная была написана как решение традиционной проблемы бинарной математики в мире, ожидающем десятичных решений