Lebegőpontos számábrázolás

Jellemzők, korlátok, hibák és néhány kifejezetten érdekes jelenség. A cél nem az, hogy a hallgató „féljen” a lebegőpontos számoktól, hanem az, hogy felismerje: ezek nem valós számok, hanem véges bithosszú, skálázott közelítések.

1. Alapgondolat: a számítógép nem a valós számokat tárolja

A matematikai valós számok halmaza folytonos és végtelenül sűrű. Egy számítógépes változó ezzel szemben véges számú bitet használ. Ezért a legtöbb valós számot nem lehet pontosan eltárolni. A lebegőpontos számábrázolás lényege: egy számot előjel, skálázó kitevő és jelentős jegyek segítségével tárolunk.

lebegőpontos szám ≈ előjel × jelentős rész × 2^kitevő

Ez a tudományos írásmód kettes számrendszerű változata. Tízes alapú analógiában:

6.022 × 10^23 vagy -1.37 × 10^-4

A „lebegő” szó arra utal, hogy a radixpont — kettes rendszerben a bináris pont — helye a kitevővel változtatható. Emiatt nagyon nagy és nagyon kicsi számok is ábrázolhatók, de az ábrázolható számok között hézagok vannak.

Tanítási kulcsmondat: a lebegőpontos típus nem „valós szám típus”, hanem véges pontosságú, relatív pontosságú számrács.

Miért nem elég az egész szám?

  • Jelek és rendszerek számításaiban amplitúdók, együtthatók, frekvenciák és energiák gyakran nem egész számok.
  • FIR/IIR szűrőkben a koefficiensek tipikusan törtek.
  • FFT, konvolúció, korreláció és numerikus integrálás sok szorzás-összeadást végez.
  • Nagy dinamikatartomány kell: például 10^-12 és 10^12 ugyanabban a számításban.
A nagy dinamikatartomány ára az, hogy a pontosság nem abszolút, hanem nagyjából relatív: nagy számok körül a szomszédos ábrázolható értékek távolabb vannak egymástól.

2. IEEE-754: előjel, kitevő, törtrész

A gyakorlatban leggyakrabban az IEEE-754 szabvány szerinti bináris lebegőpontos formátumokkal találkozunk. Két tipikus forma:

Formátum Összes bit Előjel Kitevő Törtrész Bias Precíziós bitek
float32 / egyszeres pontosság 32 1 8 23 127 24, mert normál számnál van rejtett vezető 1
float64 / dupla pontosság 64 1 11 52 1023 53, mert normál számnál van rejtett vezető 1

Normál szám esetén a dekódolás:

x = (-1)^s × (1.fraction)_2 × 2^(E - bias)

A fraction mező nem az egész mantisszát tárolja. Normál számoknál az első bit implicit: a jelentős rész 1.fraction. Ezért kapunk egy plusz precíziós bitet.

Az implicit vezető 1 jó mérnöki kompromisszum: nem kell tárolni azt, ami normált számoknál mindig 1, így ugyanannyi bitből nagyobb pontosság érhető el.

Speciális esetek

KitevőmezőTörtrészJelentés
nem nulla, nem csupa 1bárminormál szám
csupa 00+0 vagy -0
csupa 0nem nullaszubnormális szám
csupa 10+∞ vagy -∞
csupa 1nem nullaNaN
A szubnormális számok célja az, hogy az alulcsordulás ne hirtelen nullába essen, hanem legyen egy „fokozatos alulcsordulási” tartomány.

3. Interaktív bitfelbontó: mi van ténylegesen a bitekben?

Írj be egy számot, majd válassz formátumot. A demó megmutatja az előjelbitet, a kitevőmezőt, a törtrészt, a kategóriát és a tárolt értéket. Érdemes kipróbálni: 0.1, 0.2, 0.3, -0, Infinity, NaN, 1e40 float32-ben.

4. Fő jellemzők

  • Véges pontosság: csak véges sok szám ábrázolható.
  • Relatív pontosság: a relatív hiba általában kicsi, de az abszolút lépésköz a szám nagyságával nő.
  • Nagy dinamikatartomány: nagyon nagy és nagyon kicsi számok is kezelhetők.
  • Kerekítés: a műveletek eredménye általában kerekített lebegőpontos szám.
  • Speciális értékek: +0, -0, Infinity, -Infinity, NaN.
  • Nem egyenletes rács: a számegyenesen távolabb haladva a szomszédos lebegőpontos számok távolsága nő.

Gyakori konstansok

MennyiségFloat64Float32 közelítően
Gépi epszilon 1 körül 2^-52 ≈ 2.220446049250313e-16 2^-23 ≈ 1.1920928955078125e-7
Legnagyobb véges szám ≈ 1.7976931348623157e308 ≈ 3.4028234663852886e38
Legkisebb pozitív normál szám ≈ 2.2250738585072014e-308 ≈ 1.1754943508222875e-38
Legkisebb pozitív szubnormális szám ≈ 5e-324 ≈ 1.401298464324817e-45
A gépi epszilon nem azt jelenti, hogy minden szám abszolút hibája ekkora. A nagyságrend számít: 1e16 körül az egységnyi változás már túl kicsi lehet ahhoz, hogy megjelenjen.
Szigorúbb numerikus analízisben a gépi epszilon és a unit roundoff nem mindig ugyanaz. Kerekítés a legközelebbihez esetén a relatív kerekítési hiba felső korlátját gyakran körülbelül eps/2-ként használom. Oktatási bevezetőben azonban az eps jó tájékozódási skála.

5. Korlátok: mi nem fér bele?

Nem minden tizedes tört ábrázolható pontosan

Kettes számrendszerben azok a törtek ábrázolhatók végesen, amelyek nevezője egyszerűsítés után kettőhatvány. Például 1/2, 1/4, 3/8 véges bináris törtek. Ezzel szemben 1/10 nem az.

0.1_10 = 0.000110011001100110011..._2 // végtelenül ismétlődő bináris tört

Emiatt a 0.1 beírásakor a gép a legközelebbi reprezentálható bináris lebegőpontos számot tárolja.

Ez nem programozási nyelvi „hiba”, hanem a véges bináris reprezentáció következménye.

A reprezentálható számok rácsa

A következő ábra azt szemlélteti, hogy egy adott kitevőtartományban a rácspontok egyenletesek, de a következő kitevőtartományba lépve a távolság megduplázódik.

6. Tipikus numerikus hibák

1. Kerekítési hiba

A művelet matematikai eredménye általában nem ábrázolható pontosan, ezért a gép a legközelebbi reprezentálható értékre kerekít.

fl(a + b) = (a + b)(1 + δ), ahol |δ| kicsi

2. Hibaakkumuláció

Sok ezer vagy millió műveletnél a kis kerekítési hibák felhalmozódhatnak. Ez különösen fontos szűrésnél, konvolúciónál, korrelációnál és FFT-nél.

3. Katasztrofális kioltás

Ha két majdnem azonos számot kivonunk egymásból, a jelentős jegyek eltűnhetnek, és a relatív hiba drasztikusan megnőhet.

(1.000000001 - 1.000000000) // kevés értékes jegy marad

4. Abszorpció

Ha egy nagyon kis számot adunk egy nagyon nagyhoz, a kicsi teljesen elveszhet.

1e16 + 1 === 1e16 // Float64-ben igaz lehet

5. Túlcsordulás és alulcsordulás

Túl nagy eredmény Infinity-hez, túl kicsi pozitív eredmény szubnormális értékhez vagy nullához vezethet.

6. Nem asszociatív műveletek

Matematikában (a+b)+c = a+(b+c). Lebegőpontos aritmetikában ez általában nem garantált.

(a + b) + c ≠ a + (b + c)

7.1. Klasszikus példa: 0.1 + 0.2

A decimális 0.1 és 0.2 binárisan nem véges törtek, ezért az összegük sem feltétlenül pontosan 0.3 lesz.

Fontos: a jelenség nem azért van, mert „a gép rosszul ad össze”, hanem azért, mert a bemeneti számok már eleve közelítések.

7.2. Asszociativitás sérülése

Válassz három számot. A két zárójelezés eltérő kerekítési sorrendet kényszerít ki.

7.3. Abszorpció és ULP

Az ULP az adott szám körüli szomszédos lebegőpontos rácspontok távolságát jelöli. Ha a hozzáadott érték ennél lényegesen kisebb, eltűnhet.

7.4. Hibaakkumuláció és Kahan-összegzés

Sok azonos tag összeadása jó példa arra, hogyan halmozódhat a kerekítési hiba. A Kahan-összegzés egy kompenzációs változóval csökkenti a hibát.

7.5. Katasztrofális kioltás

A következő két képlet matematikailag ekvivalens, numerikusan azonban nem azonos stabilitású:

sqrt(x + 1) - sqrt(x) = 1 / (sqrt(x + 1) + sqrt(x))

7.6. Speciális értékek: NaN, Infinity, -0

Ezek nem mellékes ritkaságok. Valós numerikus programokban megjelennek osztásnál, túlcsordulásnál, érvénytelen műveletnél vagy határérték-jellegű számításnál.

8. Gyakorlati szabályok mérnöki számításokhoz

  1. Ne hasonlíts lebegőpontos számot puszta egyenlőséggel, ha számításból jött. Használj abszolút és/vagy relatív toleranciát.
  2. Skálázd a problémát. Kerüld, hogy ugyanabban a műveletben extrém nagy és extrém kicsi számok keveredjenek.
  3. Kerüld két közel azonos szám kivonását. Ha lehet, alakítsd át a képletet numerikusan stabil formára.
  4. Összegzésnél gondolj a sorrendre. Sok tag esetén a páronkénti összegzés vagy a Kahan-összegzés jobb lehet.
  5. Pénzügyi cent/pénzegység számolására ne bináris floatot használj. Gyakran egész számú cent vagy decimális típus a jobb választás.
  6. IIR szűrőknél figyelj a pólusokra, koefficienskvantálásra és skálázásra. A lebegőpontos hiba visszacsatolásban fel tud erősödni.
// Tipikus toleranciás összehasonlítás abs(a - b) <= atol + rtol * max(abs(a), abs(b))

Jelek és rendszerek kontextusában

  • FIR szűrés: sok szorzás és összeadás; az összegzés sorrendje számíthat.
  • IIR szűrés: visszacsatolás miatt a numerikus hiba dinamikailag is viselkedik.
  • Konvolúció: hosszú jeleknél a részösszegek hibája felhalmozódhat.
  • Korreláció: nagy hasonló komponensek kivonása és normalizálás érzékeny lehet.
  • FFT: elméleti O(N log N) algoritmus, de sok kerekített komplex művelettel.
A jó numerikus szemlélet nem azt jelenti, hogy minden float eredmény gyanús. Azt jelenti, hogy tudom, melyik műveleti minta hajlamos hibát felnagyítani.

9. Érdekességek, amelyek jól működnek órán

  • NaN !== NaN.
  • +0 és -0 különböző bitminták.
  • 1 / +0 = +Infinity.
  • 1 / -0 = -Infinity.
  • 0.1 + 0.2 !== 0.3.
  • 1e16 + 1 === 1e16 Float64-ben.
  • A szubnormális számokban nincs implicit vezető 1.
  • A float-rács távolsága kitevőnként skálázódik.

Rövid órai demonstrációs sorrend

  1. Mutasd meg a 0.1 + 0.2 példát.
  2. Bitfelbontóval nézesd meg a 0.1 tárolt alakját.
  3. Mutasd meg, hogy 1e16 + 1 nem változtatja meg a számot.
  4. Mutasd meg az asszociativitási ellenpéldát.
  5. Zárásként adj stabil átalakítást a sqrt(x+1)-sqrt(x) példára.
Ez a sorrend jó, mert előbb meglepetést kelt, majd megadja a strukturális magyarázatot: véges bitmezők, kitevő, mantissza, rácstávolság, kerekítés.

10. Ellenőrző kérdések

Miért nem pontos a 0.1 bináris lebegőpontos alakban?

Mert 1/10 nevezője egyszerűsítés után nem kettőhatvány. Bináris rendszerben ezért végtelenül ismétlődő tört, amelyet véges mantisszával csak közelíteni lehet.

Mi a különbség az abszolút és a relatív hiba között?

Az abszolút hiba |x̂ - x|. A relatív hiba |x̂ - x| / |x|. Lebegőpontos számoknál gyakran a relatív pontosság a természetesebb fogalom.

Miért veszélyes két közel azonos szám kivonása?

Mert a közös vezető jegyek kiesnek. A maradék kevés jelentős jegyből állhat, így a relatív hiba nagyra nőhet.

Miért lehet (a+b)+c más, mint a+(b+c)?

Mert minden részösszeg kerekítődik. Más zárójelezés más részösszegeket és ezért más kerekítési hibát adhat.

Mit jelent az, hogy a lebegőpontos számrács nem egyenletes?

A szomszédos ábrázolható számok távolsága a kitevővel nő. Nagyobb számok körül nagyobb az ULP, vagyis nagyobb a legkisebb reprezentálható változás.