While z double

0

double x =7.0;
while (x > 5.0)
{
MessageBox.Show("Przed " + x);
x--;
MessageBox.Show("Po " + x);
}
x = 1.45;
while (x > 1.44)
{
MessageBox.Show("Przed " + x);
x=x-0.005;
MessageBox.Show("Po " + x);
}

dwie petle while...
Dlaczego druga petla wykonuje sie kiedy x po obnizeniu o 0.005 ma wartosc 1.44? Dla porownania pierwsza petla po obnizeniu x do 5 nie wykonuje sie. Jak zrobic by druga petla dziala jak pierwsza ale z odejmowaniem wartosci po przecinku?

0

Komputery nigdy nie były dobre w typach zmiennoprzecinkowych. W niektórych językach nawet 0.003 * 1000 = 2.99999999 (nie stosują "niejawnych" zaokrągleń przy wypisywaniu tak jak C, C++ czy inne). Jest to pewna "niedoskonałość" związana z konwersją liczby dziesiątkowej na dwójkową i vice versa.

O ile liczba 0.5(10) to w dwójkowym 0.1(2), to 0.1(10) już o wiele ciężej zapisać: 1÷16+1÷32+1÷256+1÷512+1÷2048, czyli 0.00011001101(2) i to dalej nie jest dokładnie 0.1(10).

dokładność masz tylko stosując dzielenie przez dwa i ułamki dające się zapisać jaki a/x, gdzie x jest którąkolwiek potęgą liczby 2.

Podsumowując w przybliżeniu stosowanym przez procesor: 1.45 - 0.005 - 0.005 > 1.44.
Lepiej zastosować iterację używając typów całkowitych. W twoim wypadku można użyć inta, tyle że przemnożyć tą liczbę przez 1000.

Na giełdach gdzie liczone są duże sumy nie używa się typu float, ani double, tylko właśnie przemnożone inty, żeby nie stracić tej precyzji, co może się wiązać z ogromnymi stratami.

0

Dzieki, probowalem na flotach, ale tez niedokladne byly. Na intach dziala dobrze.
Prosta konwersja:
double d = 6.66666;
int f = (int) (d*100000); // zapisuje double do int jako liczbe calkowita

Pozniej po peli while:

d= (double) f; // zapisuje int do double jako liczbe zmiennoprzecinkowa
f=(f/100000);

i dziala:P

0

Ogólnie chyba najpopularniejszym rozwiązaniem jest porównywanie z dodatkowym epsilonem (np. a>b*(1+10-13), a<b*(1-10^-13)), choć wtedy dochodzi Ci dodatkowo to, że a>b != b<=a. Choć i tak normalnie przy liczbach zmiennoprzecinkowych a+b+c!=c+b+a.

1 użytkowników online, w tym zalogowanych: 0, gości: 1