1.1 Округлення дійсних чисел
Дійсні (дробові) числа англійською називаються floating point number – числа з плаваючою точкою: у США для розділення цілої і дробової частини числа використовується крапка. Звідси й походить назва float.
Як ми вже розбирали, при перетворенні дійсного числа (float) у ціле (int), воно завжди округлюється вниз до цілого — його дробова частина просто відкидається. А ось легко уявити ситуацію, коли дробове число потрібно округлити просто до найближчого цілого чи взагалі вгору. Що робити?
Для такого випадку в JavaScript є вбудована функція round(). Її придумали ще до створення бібліотеки Math, тому вона не входить до неї. Функції ж для округлення вниз і вверх знаходяться в бібліотеці math.
Функція Math.round()
Функція Math.round() округлює число до найближчого цілого:
Math.round(дійсне_число)
Ця функція поверне ціле число, до якого ближче передане в неї дійсне число.
Приклади:
| Команда | Результат |
|---|---|
let x = Math.round(4.1); |
4 |
let x = Math.round(4.5); |
5 |
let x = Math.round(4.9); |
5 |
Функція Math.ceil()
Функція Math.ceil() округлює число до цілого вгору:
| Команда | Результат |
|---|---|
let x = Math.ceil(4.1); |
5 |
let x = Math.ceil(4.5); |
5 |
let x = Math.ceil(4.9); |
5 |
Функція Math.floor()
Функція Math.floor() округлює число до цілого вниз:
| Команда | Результат |
|---|---|
let x = Math.floor(4.1); |
4 |
let x = Math.floor(4.5); |
4 |
let x = Math.floor(4.9); |
4 |
Якщо вам важко запам'ятати ці команди, вам допоможе невеликий урок англійської:
- math — математика
- round — круг/округлювати
- ceiling — стеля
- floor — підлога
1.2 Пристрій чисел з плаваючою точкою
Тип number в JavaScript може зберігати значення у діапазоні від -1.7*10308 до +1.7*10308. Такий гігантський діапазон значень пояснюється тим, що тип number влаштований зовсім інакше порівняно з цілими типами. Кожна змінна типу number містить два числа: перше називається мантиса, а друге — показник.
Припустимо, у нас є число 123456789, і ми зберегли його у змінну типу number. Тоді число буде перетворено до вигляду 1.23456789*108, і всередині типу number будуть зберігатися числа — 1.23456789 і 8. Червоним виділена «значуща частина числа» (мантиса), синім — показник.
Такий підхід дозволяє зберігати як дуже великі числа, так і дуже малі. Але оскільки розмір числа обмежений 8 байтами (64 біти) і частина бітів використовується для зберігання показника (а також знака числа і знака показника), максимальна довжина мантиси обмежена 15 цифрами.
Це дуже спрощений опис пристрою дійсних чисел: більш повний можна знайти за посиланням.
1.3 Втрата точності при роботі з дійсними числами
Під час роботи з дійсними числами завжди потрібно мати на увазі, що дійсні числа — неточні. Завжди будуть помилки округлення, помилки перетворення із десяткової системи у двійкову і, нарешті, найчастіше — втрата точності при складанні/відніманні чисел дуже різних розмірностей.
Останнє — найбільш несподівана ситуація для початківців у програмуванні.
Якщо з числа 109 відняти 1/109, ми отримаємо знову 109.
| Віднімання чисел дуже різних розмірностей | Пояснення |
|---|---|
| 1000000000.000000000 - 0.000000001 1000000000.000000000 |
Друге число надто мале, і його значуща частина ігнорується (виділено сірим). Червоним виділені 15 значущих цифр. |
Що тут сказати, програмування — це не математика.
1.4 Небезпека порівняння дійсних чисел
Ще одна небезпека підстерігає програмістів при порівнянні дійсних чисел. Оскільки під час роботи з цими числами можуть накопичуватися помилки округлення, можливі ситуації, коли дійсні числа мають бути рівні, але вони не рівні. І навпаки: числа мають бути не рівні, але вони рівні.
Приклад:
| Команда | Пояснення |
|---|---|
let a = 1000000000.0let b = 0.000000001let c = a – b |
У змінній a буде значення 1000000000.0.У змінній c буде значення 1000000000.0(число у змінній b надто мале). |
У наведеному вище прикладі a і c не повинні бути рівні, але вони рівні.
Або візьмемо інший приклад:
| Команда | Пояснення |
|---|---|
let a = 1.00000000000000001let b = 1.00000000000000002 |
У змінній a буде значення 1.0.У змінній b буде значення 1.0. |
На практиці дійсні числа порівнюють так:
Якщо різниця чисел (за модулем) менша, ніж якесь дуже маленьке число, вони вважаються рівними.
Приклад:
let a = 0.00000000012;
let b = 0.000000000011;
if (Math.abs(a - b) < 0.00001) {
console.log("рівні");
} else {
console.log("не рівні");
}
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ