Kezdőoldal » Számítástechnika » Programozás » Double számábrázolás hibáját...

Double számábrázolás hibáját hogyan lehet minimálisra csükkenteni egy ciklusban?

Figyelt kérdés

Az alábbi probléma egy szinte minden numerikus számítást végző programban előforduló tipikus és nagyon alapvető numerikus hibalehetőség:


Tegyük fel, hogy van egy for ciklusunk az alábbi formában:


for (double x; x < Y; x += dx)

{

// numerikus kód

}


Az a probléma, hogyha mondjuk dx=0.1-et adunk meg lépésköznek, az nem egzaktul 1/10 a double számábrázolás miatt. Tipikusan a 15 jegyből az utolsó nem stimmel. Ha nagyon sokat lépünk akkor a hiba megnövekszik, hiszen minden lépésben összeadódik. 100 lépés múlva például már az utolsó három számjegy hibás. Ha Y rögzített, és például egységnyi, akkor dx=1e-7 -nél kisebb lépésköznek nincs értelme, mert a hiba a ciklus alatt ennél nagyobbra nő. Ez egy elég durva hiba, ráadásul még semmit nem is számoltunk, csak egy ciklusunk van. Van valami library ami megoldja ezt a problémát? Vagy dx értékének tudunk választani valami speckó számot, ami egzaktul ábrázolódik double-ba?


2010. okt. 31. 16:49
 1/4 anonim ***** válasza:
Használj egy int-et ciklusváltozónak, és abból számold ki mindig a számításokhoz használt double számot!
2010. okt. 31. 20:54
Hasznos számodra ez a válasz?
 2/4 anonim ***** válasza:

Ahogy az első mondja, ne hordozd magaddal a korábbi összeadások hibáit, számold ki újra mindig. Tehát

for (double x; x < Y; x += dx)

helyett

double base, x;

for (int i(0); (x = base+i*dx)<Y; ++i)

{

//...

}

2010. okt. 31. 21:10
Hasznos számodra ez a válasz?
 3/4 A kérdező kommentje:
Sajnos nem minden esetben megoldható. A numerikus algoruitmustól függ. Vagy lehet hogy x-re jó, de vele együtt megy valami másik, aminek meg relatíe megnő a hibája ha x-et kijavítom.
2010. nov. 1. 08:51
 4/4 A kérdező kommentje:
Ennyire nem vagyok hülye, hogy ne tudnám speckó esetbe kikerülni. De az igazi megoldás egy másfajta számábrázolás lenne. Igazából a double az teljesen szar, nem látok olyn problémát, ahol előnyös lenne, nem is értem miért találták ki. Próbáltak minél kevesebb bitbe minél több számot belezsúfolni, de az ember ezekkel a számokkal számol is legtöbbször, és kevésszer van szüksége baromi nagy számokra, inkább a pontosság a fontos. Ha meg nagyobb kell, akkor választ egy longer verziót. Szóval van-e olyan library, ami mondjuk olyan számábrázolást tesz lehetővé, hogy mondjuk long int.long int*10^int, vagy valami hasonló. Ez ugyan 10-es számrendszerhez kötődik, de nem baj, mert mindenki azt hasznája, persze lehetne ennek a librarynak tetszőleges számrendszerbeli verziója. És persze az lenne a profi dolog, ha még a hibát is eltárolná egy változóban, aminek már nem kell olyan pontosnak lennie, akár lehet double is. Ha műveleteket végzünk ilyen számokkal, akkor ritkán kerülünk ki ezen tipuú számok köréből, de néha mégis (pl sin, cos, exp) ekkor jó, ha a hiba tárolódik.
2010. nov. 1. 09:20

További kérdések:





Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!