Python

1,7^2 = 2.8899999999999997 ? Или умножение в Python

Решила написать калькулятор квадратных уравнений в Python и, – вот незадача, при определенных расчетах и проверках понимаю, что что-то не так с умножением. Каким-то боком Python умножает 1.7 на 1.7 и получает число, указанное выше. В интернете не смогла найти адекватного ответа, но, поэкспериментировав, поняла, что это не единственная пара чисел с "подвохом".
2.3*2.3=5.289999999999999
И по какой-то сверхъестественной причине это вроде работает только с квадратами, ну или я просто не нашла других примеров в другом случае :'D.
Впринципе, это конечно приближенный ответ и можно было бы просто использовать round(*переменная*, 15), так как дальше по цепной реакции будут сокращаться девятки, но меня настораживает факт существования такого конфликта в пайтон, хоть и примерно понимаю его причину. (Возможно дело в системах счисления, но я бы хотела послушать людей, которые разбираются в этом)))
Используй Decimal в python(в интернете прочитай что это). А эта погрешность возникает из-за разных систем счислений. Кстати, вот реально годный канал https://www.youtube.com/watch?v=kG_ipMygRUc
AK
Adlet Kultaev
12 733
Лучший ответ
Мадам, вы взяли число с 1 знаком после запятой и возвели его в квадрат. По всем правилам вы обязаны были после этого округлить полученное значение до 2 знаков после запятой, прежде чем выводить его. Почему вы этого не сделали?
Это не специфично для Python. Это проблема всех языков, использующих обычные дробные числа, как их воспринимает процессор. На одно дробное число отводится 4 или 8 байт, и закодировать дробную часть битами нередко выходит лишь в некотором приближении.

Число 1.7 хранится в памяти с погрешностью, которая не видна при выводе: программа показывает ограниченное число дробных знаков. Однако при умножении 1.7 на 1.7 вместе с числом умножается и его погрешность. Она вылезает на один знак вверх, ближе к точке, и становится видимой при выводе.

По этой причине есть смысл:
1) округлять числа после расчетов или перед выводом до необходимого вам количества знаков;
2) сравнивать дробные числа не через строгое равенство (a == b), а через модуль разницы между ними (abs(a - b) < delta, где delta — допустимая погрешность вроде 0.00001).

Для расчетов без погрешностей вы можете воспользоваться другим типом данных — decimal:
https://docs.python.org/3/library/decimal.html
Он может оказаться более медленным и менее удобным, но позволяет обеспечить точные расчеты и контролируемое округление.
написал на DELPHI задал тип extended
результат 2.89000000000000E+0000
язык надо выбирать с понятием.
Так это во всех ЯП. Зато на Пайтоне можно исхитряться по разному. Например, число вводить как дробь, а выводить как вещественное:
import fractions
x = fractions.Fraction(input('x = ?\b'))
print(float(x * x))
Тогда в случае введения х = 1.7 выдаст 2.89, а в случае х = 2.3 ответ будет 5.29.
Числа float записываются в компьютерах неточно, если они не являются дробью двойки.
Числа в компе хранятся в двоичном виде, поэтому многие десятичные дроби превращаются в бесконечные периодические двоичные. Из-за чего какой-то кусочек приходится отбрасывать и получается неточность.

Попробуйте например это
>>> f'{1.7:.60f}'
'1.699999999999999955591079014993738383054733276367187500000000'
>>> f'{0.1:.60f}'
'0.100000000000000005551115123125782702118158340454101562500000'
Но
>>> f'{0.125:.60f}'
'0.125000000000000000000000000000000000000000000000000000000000'
потому, что 0.125 - это 1/8, а 8 - степень двойки.

Вот целый сайт сайт про это есть.
https://0.30000000000000004.com/
ПG
Про100 Gram
21 729