jaka jest najmniejsza możliwa liczba? – Programowanie słowo dnia

Marin Benčević
Marin Benčević

Obserwuj

Aug 7, 2018 · 5 min czytać

jaka jest najmniejsza liczba większa od 0? Jest to jedno z tych prostych pytań ze skomplikowanymi odpowiedziami gdzieś pomiędzy „nie ma” a „to zależy”.

jeśli zapytasz matematyka, powie Ci, że nie może być takiej liczby, bo to by złamało matematykę. Jeśli masz liczbę n, gdzie n jest najmniejszą liczbą po 0, to nie może być liczby n/2, ponieważ N jest już najmniejszą. Oznacza to, że podział się rozpada, co matematycy nie lubią.

jeśli zapytasz komputer, otrzymasz odpowiedź. W przeciwieństwie do świata rzeczywistego, komputery nie mają nieskończonej ilości liczb, ponieważ po prostu nie mogły się zmieścić. Komputery przechowują numery w rejestrach pamięci, a każdy rejestr ma ustaloną liczbę bitów. Wyobraź sobie, że masz tylko trzy cyfry. Największa liczba, jaką możesz reprezentować, to 999. Tak dzieje się w komputerze.

oznacza to, że zbiór liczb całkowitych w komputerze jest ograniczony liczbą cyfr. W komputerze jest zdecydowanie największa liczba (na przykład INT_MAX w C). Jest to liczba z maksymalną liczbą cyfr, z których wszystkie są ustawione na binarną 1. W systemie 8-bitowym liczba ta wynosiłaby 11111111.

możemy skomplikować sprawy jeszcze bardziej, włączając liczby ujemne. Jeśli mamy 8 bitów danych, możemy użyć pierwszego bitu do reprezentowania znaku liczby. 0 za plus i 1 za minus. Teraz mamy 7 bitów dla naszych cyfr, więc największa liczba to 011111111, która jest mniejsza niż nasza poprzednia największa liczba.

jeszcze nie skończyliśmy. Musimy również reprezentować liczby dziesiętne. Nawet jeśli 0.12 jest małą liczbą, to nadal ma trzy cyfry, tak jak 123. Różnica polega na tym, że jest jeszcze jedna rzecz, o której musimy pomyśleć: kropka dziesiętna, zwana także punktem radix. Musimy zapisać zarówno cyfry, jak i pozycję punktu radixa.

podczas gdy liczby całkowite są ograniczone wielkością, liczby dziesiętne są ograniczone zarówno wielkością, jak i precyzją. Jeśli masz stałą liczbę cyfr, jest tylko tyle cyfr, które możesz umieścić po kropce dziesiętnej. Dlatego komputery muszą zaokrąglać liczby dziesiętne.

jak więc przechowywać te liczby dziesiętne? Komputery rozumieją tylko liczby całkowite, więc potrzebujemy sposobu na zapisanie liczby dziesiętnej tylko za pomocą liczb całkowitych.

powiedzmy, że mamy numer 3.14. Zacznijmy od zapisania wszystkich cyfr numeru. Dostajemy 314. To jakiś początek. Wiemy, że mnożąc przez potęgi 10, możemy „przesunąć” punkt dziesiętny wokół liczby. 314 * 10^-1 to 31,4, podczas gdy 314 * 10^-2 to 3,14.

wszystko, czego potrzebujemy, aby reprezentować liczbę 3.14, to trzy liczby całkowite: 314, 10 i -2. 314 to coś, co nazywa się significand, a to są wszystkie cyfry liczby wypisane.

10 nazywa się radix lub bazą. Wiemy, że mnożąc przez potęgi 10 możemy przesuwać kropkę dziesiętną wokół liczb w bazie 10. To samo działa dla wszystkich baz liczb: w bazie 2 (lub binarnej) możesz przesunąć kropkę mnożąc przez potęgi 2.

potęga, o którą się przesuwamy, nazywa się wykładnikiem i mówi nam, gdzie jest kropka dziesiętna.

możesz zapisać każdą liczbę dziesiętną jako te trzy liczby za pomocą prostego wzoru:

number = significand * base^exponent3.14 = 314 * 10^-2
32.8 = 328 * 10^-1

komputer przechowuje liczbę dziesiętną, przechowując znak, wykładnik i significand w jednym ciągu 32 lub 64-bitowych cyfr. Zwykle jest 1 bit dla znaku, 11 bitów do przechowywania wykładnika i 53 bity do przechowywania significand, dodając do 64.

Mając to na uwadze, wróćmy do naszego pytania: Jaka jest najmniejsza liczba niezerowa? Jeśli mamy do dyspozycji tylko trzy cyfry, najmniejszą możliwą liczbą jest 0.01. Cztery cyfry oznaczają 0,001. Zauważysz tu wzór: znaczenie jest zawsze takie samo, zmienia się tylko wykładnik.

to, czego potrzebujemy, to znacząca liczba 1, ponieważ jest to najmniejsza po 0. Następnie musimy przesunąć punkt dziesiętny tak daleko, jak to tylko możliwe, w lewo. Aby to zrobić, potrzebujemy najmniejszego (najbardziej ujemnego) możliwego wykładnika.

jak mały, zależy od układu numeru w pamięci. Jeśli mamy 11 bitów dla wykładnika, możemy zapisać tylko liczbę o długości 10 bitów, z 1 bitem zarezerwowanym dla znaku. W systemie 64-bitowym najmniejszym wykładnikiem jest -308.

w końcu najmniejsza możliwa liczba W 64-bitowym systemie byłaby wokół 1 * 10^-308. To jest małe!

ustaliliśmy, że jest najmniejsza liczba. Ta liczba mówi nam, jak bardzo możemy ufać naszemu komputerowi. Jeśli robisz coś, co wymaga bardzo dużych liczb lub bardzo dokładnych liczb, musisz pamiętać o tej liczbie.

to, co właśnie obliczyliśmy, to coś, co nazywa się jednostką na ostatnim miejscu, lub ulp, z 0. Poza tym, że jest to naprawdę fajne słowo, ulp mówi nam, jaka jest minimalna odległość między dwiema liczbami w komputerze. Obliczyliśmy ulp z 0, co jest minimalną odległością pomiędzy 0 a następną liczbą.

jeśli dodasz obliczoną wartość do 0 i spróbujesz je porównać, nie będzie to ta sama liczba. Jeśli jednak dodasz wartość mniejszą niż ulp, nadal będzie to ta sama liczba, jeśli chodzi o komputer.

print(0 == 0 + ulp(0)) // false
print(0 == 0 + ulp(0) / 2) // true

dla nas jest oczywiste, że dodanie niezerowej wartości do liczby da inną liczbę, ale komputer musi gdzieś zaokrąglać, więc nie musi koniecznie stwierdzić, czy dwie liczby są takie same.

aby łatwiej porównać systemy komputerowe, używamy ulp z 1 i nazywamy to maszyną epsilon. Gdy już znasz maszynę epsilon, możesz obliczyć dowolny inny ulp za pomocą następującego wzoru:

ulp(x) = machine epsilon * radix^exponent(x)

obliczona przez nas wartość jest bardzo mała, więc prawdopodobnie nie osiągniesz tego limitu podczas kodowania. Ale obliczyliśmy wartość dla 0. Z większą liczbą cyfr potrzebnych dla lewej strony kropki dziesiętnej, tym mniej mamy dla prawej strony. Oznacza to, że im większa liczba, tym mniejsza precyzja. Innymi słowy, ulp jest funkcją bezpośrednią wykładnika. Gdy przesuniesz kropkę dziesiętną w prawo, ulp wzrasta i tracisz precyzję.

mam nadzieję, że te informacje pomogą Ci następnym razem, gdy pojawi się dziwny błąd zmiennoprzecinkowy w kodzie. Pamiętaj, komputery są dość potężne, ale nawet komputer ma swoje granice.



+