2016-11-23 7 views
1

Существует что-то чрезвычайно странное, если я выполняю некоторые обычные вычисления в Python. Если я делаю умножение без скобок, оно дает правильную вещь, но если в скобки положить некоторые вещи, то полное умножение станет равным нулю.умножение дает ноль, если я помещаю элементы в скобки (python)

Для тех, кто не верит (я знаю, что это звучит странно):

>>> print(1.1*1.15*0.8*171*15625*24*(60/368*0.75)/1000000) 
0.0 
>>> print(1.1*1.15*0.8*171*15625*24*60/368*0.75/1000000) 
7.93546875 

, как показано на this Jupyter screenshot.

Единственная разница между обоими умножениями заключается в том, что в первом есть скобки вокруг 60/368*0.75.

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

+1

о приоритете оператора, исключая скобки, уравнения не будут равны. – amin

+0

'*' и '/' имеют одинаковый приоритет, поэтому опускание парантеса будет идти слева направо. – Felk

+0

, но оба расчета равны, как это может дать такое различие? И как предотвратить такие вещи? Я это случайно заметил – Koen

ответ

2

Если разделить целые числа a, b в питона результат пол деления, таким образом, если a < b мы получим: floor(a,b)=0

С кронштейнами вы имеете операцию 60/368, которая дает 0.

Но без скобок число 60 сначала умножают все до него, что приводит к некоторой двойной значение так, делящей это значение 368 не уступает 0.

+0

'[деление целых чисел a/b на python, результат это пол разделения разделов: * в python 2 *, или 'a // b' в * python 3 *. – greybeard

2

В скобках изменить порядок оценки, и выражение внутри них оценивается в первую очередь. Здесь, поскольку 60 и 368 являются целыми литералами, они делятся на integer division - это означает, что сохраняется только «целая» часть. Поскольку 60 меньше 368, их целочисленное деление равно 0. Оттуда результат очевиден: у вас есть серия умножений и делений, где один из множителей равен 0, поэтому конечный результат также будет 0.

Чтобы предотвратить это, вы можете выразить числа как литералы с плавающей запятой - 60.0 и 368.0. (Ну, технически, просто использовать 60.0 было бы достаточно здесь, но для согласованности я рекомендую представлять все числа в виде чисел с плавающей запятой).

+0

Лучшим решением imo, если возможно, является переход на Python 3, где '/' ведет себя математически ожидаемым, а целочисленное деление имеет свой собственный оператор '//' вместо – Felk

+0

@Felk портирует все приложение на более новую версию язык, в котором десятки тонких различий во всем шоу вместо того, чтобы просто использовать согласованное соглашение для ваших числовых литералов? Лично я бы этого не сделал. – Mureinik

+0

Благодарим вас за четкое объяснение! – Koen