Нет, компьютер точен, тут дело в другом.


Как известно, компьютер, калькулятор и подобные вычислительные машины работают на нашем любимом электричестве.

При этом как-то надо с помощью этого электричества хранить и обрабатывать различные числа. Сделать это можно по разному, но создатели цифровой техники пошли по самому простому пути: обозначили нулем отсутствие электричества, а наличие - единицей.

Поскольку таким путем можно обозначить только две цифры: 0 и 1, эту систему счисления назвали двоичной. Она оказалась настолько удобной для конструирования разных вычислительных устройств, что сегодня применяется практически везде.



Тем не менее, можно создать устройства, работающие в любых других системах счисления, если это понадобится.

Когда мы даем Python какое-то число, он для себя преобразует его в двоичную систему, а нам показывает в десятичной. Чтобы мы ничего не заподозрили.

Но тщетно: мы заподозрили.

Встроенная функция bin() позволяет увидеть двоичное представление целого числа.

Чтобы не спутать двоичное представления числа с обычным, в начало добавляются символы 0b:


print(bin(10000))

0b10011100010000










print(bin(0))
print(bin(1))
print(bin(2))
print(bin(3))
print(bin(4))
print(bin(5))
print(bin(6))
print(bin(7))
print(bin(8))
print(bin(9))
print(bin(10))











0b0
0b1
0b10
0b11
0b100
0b101
0b110
0b111
0b1000
0b1001
0b1010

Видишь, у нас круглые числа - это степени десятки: 1,10,100... А тут это степени двойки: 1,2,4,8...

И дроби в двоичной системе состоят не из суммы 0.1, 0.01, 0.001 а из суммы 1/2, 1/4, 1/8 и т.п.

Соответственно, записать точно в двоичной системе можно только дробь 1/2 (0b0.1), 1/4 (0b0.01) и так далее.

Потому, хотя внешне выглядит все прилично, выисления только с этими дробями компьютер осуществит по-настоящему, без потери точности.

А десятичная дробь 0.1 = 1/10 к ним явно не относится.

Это, кстати, можно проверить экспериментально.










print(0.1)
print(0.2)
print(0.3)
print(0.4)
print(0.5)
print(0.6)
print(0.7)
print(0.8)
print(0.9)









0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9

Все дроби хорошие, кругленькие, но возведем-ка их, скажем, в десятую степень!










print(0.1**10)
print(0.2**10)
print(0.3**10)
print(0.4**10)
print(0.5**10)
print(0.6**10)
print(0.7**10)
print(0.8**10)
print(0.9**10)









1.0000000000000006e-10
1.0240000000000006e-07
5.9048999999999975e-06
0.00010485760000000006
0.0009765625
0.006046617599999997
0.02824752489999998
0.10737418240000006
0.3486784401000001

Тут-то оно и видно, что только 1/2 = 0.5 обработалась точно. Ничего страшного в этом нет - ошибка ведь составляет ничтожную величину. Просто будем это иметь в виду.

Но вот что за странные числа: 5.9048999999999975e-06 и подообные...

Что же это "e-06" означет?