Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Вопрос про деление в Python

Максим Протопопов Знаток (404), закрыт 4 года назад
Почему 1/1e-18 = 9.999999999999999e+17?? Как то можно пофиксить? Пытался я сделать калькулятор...
while True:
try:
x = float(input('Введите первое число: '))
znak = input('Выберите действие (+ - * /): ')
if znak in ('*','/','-','+'):
y = float(input('Введите второе число: '))
if znak == '*':
print(x, '*', y, '=', x * y)
elif znak == '+':
print(x, '+', y, '=', x + y)
elif znak == '-':
print(x, '-', y, '=', x - y)
elif znak == '/':
if y != 0:
print(x, '/', y, '=', x / y)
else:
print('На ноль делить нельзя!')
else:
print('Введён неверный знак действия!')
except ValueError:
print('В поле для числа был введён неправильный символ!')
Лучший ответ
Victor Surozhtsev Просветленный (34193) 4 года назад
Чё ты мучаешься? Про тип рациональных дробей слышал? Вот им как раз здесь и можно воспользоваться !

import fractions

a,b=map(fractions.Fraction,input('> ').split(' '))

c=input('+ - × ÷ > ')

if c=='÷':print(a/b)

Вводишь данные:

> 1 1е-18

+ - × ÷ > ÷

И получаешь ответ безо всяких дурацких девяток:

1000000000000000000
Максим ПротопоповЗнаток (404) 4 года назад
Если не лень, можешь объяснить, как это всё работает (вторая строка). Что такое map? Что такое split?
Victor Surozhtsev Просветленный (34193) Если делать нехрен, то можно вводить так: a=float(input('a=')) b=float(input('b=')) c=float(input('c=')) Но можно ввести и так: a,b,c=input('a b c > ').split(' ') и по приглашению, a здесь оно будет a b c > спокойно вводишь через разделитель (в данном случае - пробел!) нужные тебе три числа. Если нужен другой разделитель, например *, то так и пишешь input('a b c > ').split('*'). Но введутся, естественно, строковые значения. Чтоб перевести в вещественный тип, нужно будет писать a=float(a);b=float(b);c=float(c) Но можно перетипóвку сделать в одном операторе - числа же одного типа нужно получить! a,b,c=map(float,input('a b c > ').split(' '))
Остальные ответы
クマのプーさん Мудрец (15499) 4 года назад
Смирись, Тут всё правильно в пределах погрешности.
Это числа с плавающей точкой. Они так работают.
Максим ПротопоповЗнаток (404) 4 года назад
Я бы с радостью смирился, но не могу (( Может всё таки можно что то сделать?
クマのプーさん Мудрец (15499) а что ты хочешь сделать? вот число 1/3 не представимо в виде конечной десятичной дроби без ошибки 0.333333333333333 != 1/3 твоя проблема того же рода
Дед МазайГений (58109) 4 года назад
Однако, некоторые другие языки дают красивый результат.
クマのプーさん Мудрец (15499) По-моему предтавление double уже стандарт на уровне железа и если не используется сторонняя библиотека для длинной арифметики, то результат будет одинаковым Ну разве что при выводе округлят по-разному
Aleks Nots Просветленный (22644) 4 года назад
x = 1/1e-18
print("%.e"%x)

Вывод
===============
1e+18
>>>

Но, если вывести так
x = 1/1e-18
print("%.f"%x)

То выведет
===============
999999999999999872
>>>
Это потому, что вещественные числа имеют конечную точность и в компе они хранятся в двоичном виде, поэтому недвоичные (например десятичные) дроби не могут точно передаваться.
Похожие вопросы