JavaRush /Курси /Frontend SELF UA /Робота з дійсними числами

Робота з дійсними числами

Frontend SELF UA
Рівень 37 , Лекція 0
Відкрита

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.0
let b = 0.000000001
let c = a – b
У змінній a буде значення 1000000000.0.
У змінній c буде значення 1000000000.0
(число у змінній b надто мале).

У наведеному вище прикладі a і c не повинні бути рівні, але вони рівні.

Або візьмемо інший приклад:

Команда Пояснення
let a = 1.00000000000000001
let b = 1.00000000000000002
У змінній a буде значення 1.0.
У змінній b буде значення 1.0.

На практиці дійсні числа порівнюють так:

Якщо різниця чисел (за модулем) менша, ніж якесь дуже маленьке число, вони вважаються рівними.

Приклад:

JavaScript
    
      let a = 0.00000000012;
      let b = 0.000000000011;

      if (Math.abs(a - b) < 0.00001) {
        console.log("рівні");
      } else {
        console.log("не рівні");
      }
    
  
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ