Przejdź do głównej zawartości

Bug #078

🪲 Znajdź buga

const minVal = Number.MIN_VALUE

console.log(0 / 0)
console.log(minVal / minVal)

console.log(0 * 0)
console.log(minVal * minVal)

console.log(minVal + 1)
console.log(minVal - 1)

console.log(minVal)

Jakie wartości zostaną zalogowane do konsoli?

🧪 Rozwiązanie

const minVal = Number.MIN_VALUE

console.log(0 / 0) // NaN
console.log(minVal / minVal) // 1

console.log(0 * 0) // 0
console.log(minVal * minVal) // 0

console.log(minVal + 1) // 1
console.log(minVal - 1) // -1

console.log(minVal) // 5e-324

JavaScript posiada w obiekcie Number własność MIN_VALUE, która zwraca najniższą, zmiennoprzecinkową, dodatnią wartość liczbową, jaką może obsłużyć.

Innymi słowy, jest to najmniejsza dodatnia wartość liczbowa bliska 0.

Liczba ta może się różnić w zależności od silnika implementującego specyfikację ECMAScript.

Specyfikacja ECMAScript nie narzuca konkretnej liczby, a jedynie wskazuje, że powinna to być najmniejsza liczba, jaką jest w stanie obsłużyć, w postaci liczby zmiennoprzecinkowej, implementacja danego języka.

Najpopularniejszy silnik implementujący JavaScript, V8, jest w stanie obsłużyć liczbę dodatnią 2-1074, czyli 5E-324 (w zapisie naukowym), lub inaczej, 5⨉10-324.

5e-323 > Number.MIN_VALUE zwróci prawdę.

5e-324 > Number.MIN_VALUE zwróci fałsz.

5e-324 === Number.MIN_VALUE zwróci prawdę.

Jednak w przypadku operacji matematycznych nie możemy polegać na tej wartości, podobnie jak w przypadku operacji na liczbach zmiennoprzecinkowych.

Niedokładne ich zaokrąglanie pojawia się np. przy działaniu\ 1 + 5e-16\ i zamiast\ 1.0000000000000005\ dostajemy\ 1.0000000000000004

1 + 5e-17 zwróci już tylko 1 i wraz ze zmniejszaniem liczby zmiennoprzecinkowej poprzez dopisywanie kolejnych miejsc po przecinku, będzie dalej otrzymywać zaokrąglony wynik dodawania, 1.

0 / 0 zwróci nam NaN, ale minVal / minVal zwróci 1, wyraźnie pokazując, że minVal zerem nie jest.

0 * 0 zwróci 0, niestety tak samo jak minVal * minVal, co może sugerować, że minVal zerem jednak jest.

W rzeczywistości jest to jednak pułapka i to ten sam problem, który dotyka operacji matematycznych wykonywanych na wszystkich zmiennoprzecinkowych liczbach, we wszystkich językach programowania.

🎢 Plac zabaw

Otwórz edytor w nowym oknie

📑 Linki

❤️ Podobają Ci się bugi JS?

Podziel się linkiem ze znajomymi:
https://codisity.pl/100-bugow-js