Неожиданный результат отрицательного целочисленного деления

В моем приложении я столкнулся со следующим и был удивлен результатами:

8/-7=-2 (оба числа).

что это значит?


person Vivek S    schedule 04.04.2011    source источник


Ответы (5)


Для фактических значений, то есть 8.0/(-7.0), результат примерно равен -1.143.

Ваш результат с использованием целочисленного деления округляется в меньшую сторону в сторону более отрицательного значения -2. (Это также известно как «этажное деление»)

Вот почему вы получите несколько озадачивающие ответы:

>>> 8/(-7)
-2
>>> 8/7
1

Примечание. Это «исправлено» в Python 3, где результатом 8/(-7) будет -1.143. Поэтому, если у вас нет причин использовать Python 2, вам следует обновиться. ;)

В Python 3, если вы все еще хотите целочисленное деление, вы можете использовать оператор //. Это даст вам тот же ответ, что и 8/(-7) в Python 2.

Вот предложение по улучшению Python на эту тему: PEP 238 -- Изменение оператора подразделения

person Chris Cooper    schedule 04.04.2011
comment
@Ира: Ага! Однако они изменили это для Python 3. - person Chris Cooper; 04.04.2011
comment
Кажется, что он должен округляться до нуля, если он собирается округляться. - person intuited; 04.04.2011
comment
@intuited: Ну, похоже, возможно, но только если вы не думаете как компьютер. 5/2 — это то же самое, что сдвиг вправо на один бит, вы получите 2 в обоих случаях. Тогда -5/2 должно быть таким же, как сдвиг вправо -5, а это -3. Проблема здесь, конечно, в том, что Python — это язык высокого уровня, и вам не обязательно знать это. Вот почему целочисленное деление изначально было неверным, и теперь это исправлено. - person Lennart Regebro; 04.04.2011
comment
@Lennart: так что вы делите -5 на 2 и получаете -3 с остатком 1. Чтобы погасить наш долг в 5 эму перед вами, каждый из нас заплатит вам по 3 эму, а вы предоставите нам одного эму, чтобы отправить нас обоих домой удачи. Конечно, имеет смысл, я думаю. - person intuited; 04.04.2011
comment
@intuited: Ах, да, остаток, я согласен, довольно неожиданный. :-) - person Lennart Regebro; 04.04.2011
comment
@intuited: a должно быть равно (a//b)*b + a%b. Таким образом, -5//2 == -3. - person Neil G; 07.04.2011
comment
@Neil: я ожидал, что -5 // 2 == -2 и -5 % 2 == -1. Другими словами, мы все еще должны вам эму в следующий раз. - person intuited; 07.04.2011
comment
@intuited: это имеет смысл, но разве вам не нужны -5 % 2 == 5 % 2, поскольку они находятся в одном классе эквивалентности? - person Neil G; 07.04.2011
comment
@LennartRegebro: для всех x и y в области натуральных или действительных чисел с использованием оператора деления, определенного для области, (n + d)/d = (n/d)+1. Python определяет целочисленное деление таким образом, что эта полезная аксиома сохраняется, даже когда n отрицательно. Даже если некоторые люди могут ожидать, что целые числа должны заимствовать (-n)/d = -(n/d) у действительных чисел, эта аксиома очень редко бывает полезной. При попытке извлечь цифры из числа наличие -123 по модулю 10 дает 7 не очень полезно, но получение -3 не лучше. - person supercat; 19.12.2013
comment
@intuited Я думаю, что именно так это работает в математике (по модулю арифметики). Языки программирования в основном просто соблюдают это определение. - person xji; 22.05.2016

Python всегда выполняет «деление пола» как для деления отрицательных чисел, так и для деления положительных чисел.

То есть

1/10 = 0
1/-10 = -1

Но иногда нам нужно, чтобы 1/-10 было 0

Я понимаю, что это можно сделать, сначала используя деление с плавающей запятой, а затем приведя результат к int, например.

int(float(1)/-10) = 0

Это отлично работает для меня, нет необходимости импортировать будущее подразделение или обновляться до Python 3.

Надеюсь, это поможет вам~

person ZH.Jay    schedule 20.07.2015

чтобы python автоматически преобразовывал целочисленное деление в число с плавающей запятой, вы можете использовать:

from __future__ import division

Теперь:

8/-7=-1.1428571428571428

эта функция отсутствует в стандартном Python 2, чтобы не нарушать существующий код, основанный на целочисленном делении. Однако это поведение по умолчанию для Python 3.

person Andrea Zonca    schedule 04.04.2011

Когда оба значения являются целыми числами, при делении Python использует деление по полу.

person Lossy    schedule 04.04.2011

В python оператор / предназначен для целочисленного деления. Вы можете рассматривать это как деление с плавающей запятой, за которым следует операция floor.

Например,

8/7 == этаж(8.0/7.0) == 1

8/-7 == пол(8,0/-7,0) == -2

person Rumple Stiltskin    schedule 04.04.2011
comment
Нет, / не для целочисленного деления, это для деления. Однако в Python 2 деление двух целых чисел вернет целое число. Это удивительно и исправлено в Python 3. - person Lennart Regebro; 04.04.2011
comment
@Lennart: Не совсем шок для программистов на C или для тех, кто читал руководство, и не ошибся. - person John Machin; 04.04.2011
comment
@John: Это нарушает основные принципы Python и, следовательно, может быть названо неправильным в контексте Python. - person Lennart Regebro; 04.04.2011
comment
@ stackoverflowuser2010 Нет, это неожиданно для программиста на C/C++, который не знает Python. Однако и для них это не является чем-то неправильным. - person Lennart Regebro; 31.08.2016