P003 - Błąd zaokrąglenia liczby rzeczywistej
Program uruchomiono w środowisku Bloodshed Dev-C++ 4.9.9.2
// I Liceum Ogólnokształcące
// im. K. Brodzińskiego
// w Tarnowie
//--------------------------
// Koło informatyczne 2006/7
//--------------------------
// Program: P003
//--------------------------

#include <iostream>
#include <iomanip>

using namespace std;

main()
{
  float x = 0;

  for(int i = 1; i <= 10; i++) x += 0.1; 
   
  if (x == 1)
    cout << "OK\n\n";
  else
    cout << "NIE OK\n\n";
  system("pause");
}

 

Widok okienka konsoli w uruchomionym programie
NIE OK

       Wyjaśnienie

Liczba rzeczywista LR jest zapisywana w komputerach w postaci specjalnego kodu zmiennoprzecinkowego. W kodzie tym liczba reprezentowana jest przez dwie inne liczby - mantysę m oraz cechę c - zgodnie ze wzorem:

obrazek

Cecha c jest liczbą całkowitą ze znakiem, natomiast mantysa m jest ułamkiem właściwym, którego mianownik jest zawsze równy pewnej potędze liczby 2. Zatem mantysa może przyjmować tylko wartości, które dają się przedstawić w postaci ułamka:

obrazek

Gdzie x jest liczbą całkowitą ze znakiem, a n określa liczbę bitów mantysy.

Zwróć uwagę, iż ułamka dziesiętnego 0,1 nie da się przedstawić w tej reprezentacji. Aby było to możliwe, licznik ułamka musiałby być dokładnie 10 razy mniejszy od mianownika, a żadna potęga liczby 2 nie dzieli się przez 10 bez reszty. Wyjaśnienie jest bardzo proste. Potęgi liczby 2 można rozłożyć jedynie na iloczyn czynników 2, np.

obrazek

Natomiast podzielność przez 10 = 2 x 5 wymaga w dzielonej liczbie obecności czynnika 5, którego tutaj nie ma. Wnioskujemy zatem, iż ułamek dziesiętny 0,1 można przedstawić w reprezentacji zmiennoprzecinkowej tylko z pewną dokładnością:

obrazek

W programie dodajemy dziesięć razy taką przybliżoną wartość ułamka 0,1. Na przykład załóżmy, iż mantysa jest 24 bitowa:

obrazek

W efekcie wynik nie jest równy dokładnie 1 i program wypisuje drugi napis, zamiast spodziewanego napisu pierwszego.

 

Dokładny opis liczb rzeczywistych znajdziesz w artykule o binarnym kodowaniu liczb.

 


   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2024 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe