Деление Python - PullRequest
       31

Деление Python

126 голосов
/ 02 июня 2010

Я пытался нормализовать набор чисел от -100 до 0 в диапазоне 10-100, и у меня возникли проблемы только с тем, чтобы заметить, что даже без переменных вообще это не оценивает то, как я ожидал :

>>> (20-10) / (100-10)
0

Деление поплавка тоже не работает:

>>> float((20-10) / (100-10))
0.0

Если любая из сторон дивизии разыграна в поплавок, она будет работать:

>>> (20-10) / float((100-10))
0.1111111111111111

Каждая сторона в первом примере оценивается как int, что означает, что окончательный ответ будет приведен к int. Поскольку 0,111 меньше 0,5, оно округляется до 0. На мой взгляд, оно не прозрачно, но, думаю, так оно и есть.

Какое объяснение?

Ответы [ 12 ]

239 голосов
/ 02 июня 2010

Вы используете Python 2.x, где целочисленные деления усекаются, а не становятся числами с плавающей запятой.

>>> 1 / 2
0

Вы должны сделать один из них float:

>>> float(10 - 20) / (100 - 10)
-0.1111111111111111

или from __future__ import division, что заставляет / принять поведение Python 3.x, которое всегда возвращает число с плавающей запятой.

>>> from __future__ import division
>>> (10 - 20) / (100 - 10)
-0.1111111111111111
19 голосов
/ 02 июня 2010

Вы вводите целые числа, поэтому Python возвращает вам целое число :

>>> 10 / 90
0

Если после этого вы разыграете это число с плавающей точкой, округление будет уже выполнено, другими словами, 0 целое число всегда будет равно 0 с плавающей точкой.

Если вы используете поплавки по обе стороны от деления, то Python даст вам ожидаемый ответ.

>>> 10 / 90.0
0.1111111111111111

Итак, в вашем случае:

>>> float(20-10) / (100-10)
0.1111111111111111
>>> (20-10) / float(100-10)
0.1111111111111111
11 голосов
/ 02 июня 2010

Вам нужно изменить его на число с плавающей точкой, прежде чем вы сделаете деление. То есть:

float(20 - 10) / (100 - 10)
10 голосов
/ 02 августа 2015

В Python 2.7 оператор / является целочисленным делением, если входные данные являются целыми числами:

>>>20/15
1

>>>20.0/15.0
1.33333333333

>>>20.0/15
1.33333333333

В Python 3.3 оператор / является делением с плавающей запятой, даже если входные данные являются целочисленными.

>>> 20/15
1.33333333333

>>>20.0/15
1.33333333333

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

Оператор // является оператором целочисленного деления в Python 2.7 и Python 3.3.

В Python 2.7 и Python 3.3:

>>>20//15
1

Теперь посмотрим сравнение

>>>a = 7.0/4.0
>>>b = 7/4
>>>print a == b

Для вышеприведенной программы вывод будет False в Python 2.7 и True в Python 3.3.

В Python 2.7 a = 1.75 и b = 1.

В Python 3.3 a = 1.75 и b = 1.75 только потому, что / является делением с плавающей точкой.

8 голосов
/ 21 ноября 2014

Это связано с версией python, которую вы используете. В основном он принимает поведение C: если вы разделите два целых числа, результаты будут округлены до целого числа. Также имейте в виду, что Python выполняет операции слева направо, что играет роль при типизации.

Пример: Поскольку этот вопрос всегда возникает у меня в голове, когда я выполняю арифметические операции (нужно ли преобразовать в число с плавающей точкой и какое число), представлен пример из этого аспекта:

>>> a = 1/2/3/4/5/4/3
>>> a
0

Когда мы делим целые числа, неудивительно, что оно округляется ниже.

>>> a = 1/2/3/4/5/4/float(3)
>>> a
0.0

Если мы введем последнее целое число с плавающей запятой, мы все равно получим ноль, поскольку к моменту, когда наше число разделится на число с плавающей точкой, уже станет 0 из-за целочисленного деления.

>>> a = 1/2/3/float(4)/5/4/3
>>> a
0.0

Тот же сценарий, что и выше, но смещение типа float немного ближе к левой стороне.

>>> a = float(1)/2/3/4/5/4/3
>>> a
0.0006944444444444445

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

Дополнительно 1: Если вы пытаетесь ответить на этот вопрос, чтобы улучшить арифметическую оценку, вы должны проверить this

Дополнительно 2: Пожалуйста, будьте осторожны в следующем сценарии:

>>> a = float(1/2/3/4/5/4/3)
>>> a
0.0
4 голосов
/ 22 августа 2014

Указание числа с плавающей точкой, поместив '.' после того, как число также заставит его по умолчанию плавать.

>>> 1 / 2
0

>>> 1. / 2.
0.5
2 голосов
/ 02 июня 2010

Сделайте хотя бы один из них с плавающей точкой, тогда это будет деление с плавающей точкой, а не целое число:

>>> (20.0-10) / (100-10)
0.1111111111111111

Бросить результат на плавание слишком поздно.

1 голос
/ 30 июня 2018

В питоне cv2 не обновляется расчет деления. Итак, вы должны включить from __future__ import division в первую строку программы.

0 голосов
/ 08 октября 2017

Лично я предпочел вставить 1. * в самом начале. Так выражение становится примерно таким:

1. * (20-10) / (100-10)

Как я всегда делаю для некоторой формулы, например:

accuracy = 1. * (len(y_val) - sum(y_val)) / len(y_val)

, поэтому невозможно просто добавить .0 как 20.0. И в моем случае, перенос с float() может немного потерять читаемость.

0 голосов
/ 22 февраля 2017

Я несколько удивлен, что никто не упомянул, что оригинальному постеру могло бы понравиться рациональное число в результате. Если вас это заинтересует, у программы на Python Sage есть ваша спина . (В настоящее время все еще основывается на Python 2.x, хотя 3.x находится в стадии разработки.)

sage: (20-10) / (100-10)
1/9

Это решение не для всех, потому что оно делает некоторую предварительную подготовку, поэтому эти числа не int с, а элементы класса Sage Integer. Тем не менее, стоит упомянуть как часть экосистемы Python.

...