Skocz do zawartości

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.
  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Zdjęcie

Floaty i ich wadyCzyli o liczbach zmiennoprzecinkowych słów kilka


  • Nie możesz napisać tematu
  • Zaloguj się, aby dodać odpowiedź
1 odpowiedź w tym temacie

#1 GwynBleidD

    Godlike

  • Przyjaciel

Reputacja: 1 869
Godlike

  • Postów:3 066
  • Steam:steam
  • Lokalizacja:Przemyśl
Offline

Napisano 26.12.2014 01:52

*
Popularny

Float jest dość ciekawym typem liczbowym, odmiennym dość od całkowitych liczb. Prawie każdy, kto używa liczb z "przecinkiem" w kodzie używa do nich właśnie floatów, nawet nie wiedząc w co się pakuje...

 

Ale czym jest float?

Float, a raczej floating point to sposób, a raczej grupa sposobów służąca do zapisania liczby niecałkowitej o nieznanej precyzji. Implementacji jest wiele, szkoda się zagłębiać które bity w której z nich co oznaczają i ile mamy możliwości zapisania zera. Skupmy się na tym, jak ogólnie zbudowany jest float.

 

Float wziął się od notacji naukowej, czyli zamiast zwykłej liczby z przecinkiem, np 279.33333 jak zapisuje ją prawie każdy, notacja naukowa zapisuje tą liczbę tak: 2.7933333 * 10^2, gdzie ^ to operator potęgowania. Jak to działa chyba każdy wie, a jak nie wie to niech zaglądnie na wikipedię.

 

Jest jednak pewna różnica, z której biorą się wszystkie problemy. Otóż komputery operują na bitach, czyli zerach i jedynkach, a nie tak jak większość ludzkiej cywilizacji, na cyfrach od 0 do 9. Dlatego liczba we floacie jest zapisana w systemie dwójkowym, przykład: 1.1011010 * 2^3. Oczywiście przykład ten nie ma nic do poprzedniego, bo mi się przeliczać nie chciało.

 

Dlaczego komputery używają notacji naukowej, a nie "szkolnej"? Stąd się właśnie bierze floating point, czyli pływający przecinek. A pływanie tego przecinka zapewnia potęga do której podnosimy dwójkę. Dzięki temu możemy dość znacznie oszczędzić miejsce zajmowane przez długą liczbę, tracąc trochę na jej dokładności, jednak relatywnie do rzędu wielkości liczby, co prawie nigdy nie będzie miało znaczenia...

 

Jednak poprzez to, oraz pewien niuans konwersji systemów liczbowych... Przykład:

 

Gdy podzielisz 1 przez 3 i będziesz to chciał zapisać w ułamku dziesiętnym to wyjdzie Ci 0.(3), czyli 0.33333333333... i tak tych trójek w nieskończoność. Człowiek rozumie okresowość, komputer niezbyt więc zapisze tyle trójek ile jest w stanie, co powoduje pewną degradację dokładności.

 

A teraz wyobraź sobie, że prawie każde dzielenie, które w systemie binarnym da się zapisać nieokresowo, w systemie dwójkowym jest okresowe. Ba! pojedyncze liczby są konwertowane na okresowe, dla przykładu 0.1 w systemie dziesiętnym to 0.0(0011) w systemie binarnym, czyli liczba okresowa, która przez komputer zostanie ucięta gdzieś tam na końcu. I dodanie 0.1 do 0.1 nie da 0.2, ale coś zbliżonego do 0.2!

 

I tu pojawiają się częste błędy, zwłaszcza gdy potrzeba nam tej precyzji np w operacjach finansowych, bo gdy jeszcze to zaokrąglimy do setnych albo tysięcznych to nagle nam grosz gdzieś ubywa albo grosz gdzieś mamy więcej...

 

Co robić? Jak żyć?

Unikać floatów!

 

Tak, dosłownie unikać floatów! W większości przypadków ich nie potrzebujemy! prosty przykład, operacje gotówkowe. Przecież możemy operować cały czas na groszach! W ten sposób unikamy całkowicie ułamków i floatów. Jeśli chcemy być dokładni do 0.1 grosza, proszę bardzo: możemy przyjąć 0.1 grosza jako jednostkę bazową, dzięki czemu 1 grosz będzie odpowiadał 10 naszym jednostkom, więc nadal operujemy na liczbach całkowitych. Chcemy wyświetlić coś w złotówkach? Podzielmy to na złotówki i grosze (dzieleniem oraz modulo) i wyświetlmy jako 2 osobne liczby, oddzielone przecinkiem.

 

W wielu miejscach w kodzie mamy wyraźnie ograniczoną precyzję do pewnej ilości miejsc po przecinku, stosujmy więc liczby o 100, 1000, 10000 albo i więcej razy większe i na nich operujmy. później wystarczy postawić kropkę i po sprawie.

 

Niektóre języki programowania (niestety pawn nie należy do nich) i prawie wszystkie silniki baz danych posiadają typ stałoprzecinkowy! Dzięki niemu nie musimy dostawiać ręcznie przecinka, musimy jednak pamiętać, że raz postawionego przecinka na etapie pisania programu już nie przesuniemy bez zmiany programu (stąd typ nazywa się stałoprzecinkowy).


  • +
  • -
  • 19

NIE pomagam na PW. Nie trudź się, na zlecenia nie odpiszę... Od pomagania jest forum.
NIE zaglądam w tematy wysłane na PW. Jeśli są na forum to prędzej czy później je przeczytam. Jeśli mam co w nich odpisać, to odpiszę.
 
1988650.png?theme=dark


#2 Skull.

    Wszechpomocny

  • Użytkownik

Reputacja: 70
Pomocny

  • Postów:314
  • Steam:steam
  • Imię:Tajemnica
  • Lokalizacja:Woj. Wielkopolskie
Offline

Napisano 18.03.2015 12:08

:o

Nawet nie wiedziałem takich rzeczy o tym :o

 

:plus: Poleciał, na pewno się przyda ten poradnik nie jednej osobie  ^D^  ^D^  ^D^


  • +
  • -
  • 0




Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych