0

Столкнулся со странным поведением округления на Python.

n = 12345
for i in range(2,9):
    k = n/10**i
    f = '%%0.%sf'%(i-1)
    s = f%k
    err = ''
    if s[-1] == '4':
        err = '<---- why rounding result ends with 4'
    print('format', f, 'of', k, 'is', s , err)

format %0.1f of 123.45 is 123.5 format %0.2f of 12.345 is 12.35 format %0.3f of 1.2345 is 1.234 <---- why rounding result ends with 4 format %0.4f of 0.12345 is 0.1235 format %0.5f of 0.012345 is 0.01235 format %0.6f of 0.0012345 is 0..001234 <---- why rounding result ends with 4 format %0.7f of 0.00012345 is 0.0001234 <---- why rounding result ends with 4

Ошибка повторяется и, например, в командной строке линукса

echo 0.0012345 | awk '{printf("%0.6f", $s)}'
0.001234

Скорее проблема в точности вещественных чисел, но уж больно число обычное 12345. Как с этим бороться? И нужно ли?

Ilgiza
  • 1
  • 1
    Число не обычное, для записи 1.2345 действительно не хватает точности и оно на самом деле равно 1.2344999999999999307220832633902318775653839111328125 (аналогичная ситуация с 0.0012345 и 0.00012345) – andreymal Sep 20 '22 at 10:36
  • Ну и с остальными числами ситуация аналогичная, просто они «неточные» в сторону увеличения и поэтому создаётся иллюзия правильного округления; например, 123.45 на самом деле равно 123.4500000000000028421709430404007434844970703125 – andreymal Sep 20 '22 at 10:38
  • В Python используется "банковское" округление, из-за этого при отбрасывании последней 5-ки, например 1.25 округлится до 1.2, а 1.35 до 1.4 (будет округлять до последней четной цифры). Но в целом на результат будет влиять и неточность представления чисел с плавающей точкой. – insolor Sep 20 '22 at 10:42
  • @insolor банковское округление ни при чём, точно такое же поведение и в Python 2, в котором нет банковского округления – andreymal Sep 20 '22 at 10:43
  • @andreymal наверное соглашусь. Похоже, что банковское округление применимо только для двоичных дробей, вида N/M, где M - степень двойки, тогда в десятичной дроби в конце будет точная 5-ка, в остальных случаях будет отклонение от точного значения в одну или другую сторону. P.S. ну или еще для каких-то спец случаев, когда в конце 5-ка, и в двоичной системе получается точное число. – insolor Sep 20 '22 at 10:49

0 Answers0