While z double

Odpowiedz Nowy wątek
2011-08-06 13:36
Jonny B.
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?

Pozostało 580 znaków

2011-08-06 14:28
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.

Pozostało 580 znaków

2011-08-06 18:04
Jonny B.
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

Pozostało 580 znaków

2011-08-06 21:04
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.

edytowany 2x, ostatnio: Zjarek, 2011-08-06 21:05

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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