🔍
Почему 0.1 + 0.2 !== 0.3 в JavaScript?Всем привет! Сегодня разберёмся раз и навсегда, почему в JavaScript:
0.1 + 0.2 === 0.30000000000000004 // true
Кажется, что это баг в JS, но на самом деле — нет. JavaScript использует формат
IEEE 754 double precision — это
64-битное представление чисел с плавающей точкой.
---
💡
Почему возникает ошибка?Некоторые десятичные дроби, например
0.1 и
0.2, невозможно
точно представить в двоичной системе. Они превращаются в бесконечные двоичные дроби.
---
📐
Как `0.1` представляется в двоичной системе?Чтобы перевести дробную часть числа в двоичную систему, мы
умножаем её на 2 и фиксируем целую часть результата. Вот шаги:
0.1 * 2 = 0.2 → 0
0.2 * 2 = 0.4 → 0
0.4 * 2 = 0.8 → 0
0.8 * 2 = 1.6 → 1
0.6 * 2 = 1.2 → 1
0.2 * 2 = 0.4 → 0
0.4 * 2 = 0.8 → 0
0.8 * 2 = 1.6 → 1
0.6 * 2 = 1.2 → 1
... и так далее
🔁 В итоге мы получаем бесконечную
периодическую двоичную дробь:
0.1₁₀ = 0.00011001100110011001100...₂
---
📦
Далее сдвигаем на 4 позиции. Почему?Чтобы сохранить число в формате IEEE 754, его нужно записать в
нормализованной форме:
1.значащие_биты × 2^экспонента
Мы сдвигаем запятую так, чтобы первая единица оказалась перед точкой:
0.0001 10011001100110011...
↓
1.10011001100110011... × 2⁻⁴
То есть сдвигаем на
4 позиции влево, и поэтому
экспонента = -4. Это и есть часть формата IEEE 754.
---
🧮
Что делает JavaScript?Он берёт ближайшее возможное двоичное значение, которое можно представить в 64 битах:
1.1001100110011001100110011001100110011001100110011010 × 2⁻⁴
Это —
ровно 52 бита точности, и последняя цифра округлена вверх.
Теперь, если пересчитать это значение обратно в десятичную форму, получится:
0.1000000000000000055511151231257827021181583404541015625
То есть
0.1 в JS — это не ровно
0.1, а немного больше. Проверка:
console.log(0.1.toPrecision(60))
// → '0.1000000000000000055511151231257827021181583404541015625'
---
📌
То же самое происходит с `0.2` — оно представляется как:
0.200000000000000011102230246251565404236316680908203125
Поэтому при сложении
0.1 + 0.2 мы получаем:
≈ 0.3000000000000000444...
А
0.3 в памяти — это
другое приближённое значение, поэтому:
0.1 + 0.2 === 0.3 // false
---
Собственно говоря вот и вся магия 💫
📚
Кстати, про достоверные источники...В универе на магистратуре в Англии нас всегда учили что все источники информации должны быть проверенными и надежными! Вот например Wikipedia вообще НЕ надежный источник информации 😂
И нам приходилось искать все эти проверенные статьи и мы гуглили не просто в Гугле а на
https://scholar.google.comМожете попробовать поискать информацию на
https://scholar.google.com и вам выйдут только академические статьи.