Numerikus ábrázolás · DSP · beágyazott rendszerek

Fixpontos számábrázolás részletesen

A fixpontos szám nem „egyszerűbb lebegőpont”, hanem egész kódok rögzített skálázása. Ebben a tananyagban a Q-formátumot, a tartomány–felbontás kompromisszumot, az overflow-t, a kerekítési hibát és a szűrőalgoritmusokban megjelenő következményeket tárgyalom, majd kritikus összevetést adok a lebegőpontos ábrázolással.

1. A legfontosabb modell: egész szám + skálafaktor

A fixpontos ábrázolásban a bitminta önmagában egy egész számot kódol. A „bináris pont” helyét nem a hardver tárolja, hanem a programozó, a fordító, a DSP-könyvtár vagy a dokumentált interfész értelmezi. Emiatt a fixpont lényegében szerződés a kód és a valós érték között.

valós érték = egész_kód · 2−F x̂ = q · 2−F q ∈ egész számok F = törtrész bitek száma

Ha például F = 7, akkor a kód q = 64 a 64 · 2⁻⁷ = 0.5 értéket jelenti. Ugyanez a bitminta más F mellett más valós szám lenne. Ezt a hallgatók gyakran alulértékelik: a bitminta és az érték között nincs önálló, univerzális kapcsolat.

Kritikus megfigyelés: a fixpont nem automatikusan „pontosabb” vagy „gyorsabb”. Pontosabb akkor lehet, ha a skálázást a feladathoz illesztjük. Gyorsabb akkor, ha a célhardver egész aritmetikája erős, a lebegőpontos egység pedig hiányzik vagy lassú.

Rövid analógia

A fixpontos szám olyan, mintha minden értéket milliméterben tárolnék egész számként, de méterként értelmezném vissza.

Tárolt egészSkálaValós érték
123410⁻³1.234 m
12342⁻¹⁰1.205078125
A skála megváltoztatása nem módosítja a biteket, de módosítja az értelmezett fizikai mennyiséget. Ezért a fixpontos hibák jelentős része nem „matematikai”, hanem skálázási fegyelmezetlenségből ered.

2. Q-formátum: hol van a bináris pont?

A Q-formátum a fixpontos értelmezés rövid jelölése. A jelölésben sajnos van szakirodalmi ingadozás, ezért egy kurzusban mindig explicit módon definiálni kell, hogy a jelbitet beleszámoljuk-e. Ebben a tananyagban az alábbi konvenciót használom.

Előjeles kétkomplementes QI.F, összesen N bit: N = 1 + I + F 1 jelbit + I egészérték-bit + F törtrész-bit q_min = −2N−1 q_max = 2N−1 − 1 x_min = −2I x_max = 2I − 2−F Δ = 2−F

A Δ a legkisebb lépésköz, vagyis a fixpontos rács felbontása. Több törtrészbit finomabb felbontást ad, de ugyanakkora teljes bitszám mellett csökkenti a tartományt.

FormátumNIFTartományLépésközTipikus használat
Q0.15 vagy gyakran Q1516015 [−1, 0.999969482…]2⁻¹⁵ ≈ 3.05·10⁻⁵normalizált DSP jel, koefficiens
Q1.1416114 [−2, 1.999938965…]2⁻¹⁴kisebb túlvezérlési tartalék
Q7.81678 [−128, 127.99609375]2⁻⁸szenzoradat, vezérlés
UQ0.8808 [0, 0.99609375]2⁻⁸előjel nélküli arány, kitöltési tényező
Jelölési csapda: egyes források a Q1.15 jelöléssel 16 bites, előjeles formátumot értenek, ahol az „1” a jelbitet is magában foglalja. Más forrásoknál a jelbit külön áll, így Q1.15 17 bitet jelentene. Mérnöki dokumentumban ezért mindig meg kell adni: N, F, előjelesség, overflow mód, kerekítés módja.

Kétkomplementes aszimmetria

Előjeles kétkomplementes formátumban eggyel több negatív egész kód van, mint pozitív. Emiatt a fixpontos tartomány is aszimmetrikus.

8 bit, F = 7: q ∈ [−128, 127] x ∈ [−1.0000000, 0.9921875] −1 pontosan ábrázolható, +1 nem ábrázolható.
Ez nem puszta esztétikai részlet. Például abs(INT_MIN) kétkomplementes egészben nem fér el ugyanabban a bitszélességben. Ugyanez a jelenség fixpontos kódokra is átöröklődik.

3. Interaktív kvantáló: tartomány, felbontás, hiba

Az alábbi demonstrációban előjeles kétkomplementes fixpontot használok. A bemeneti valós értéket egész kóddá kvantálom, majd ugyanazzal a skálával visszaalakítom. Figyelje meg, hogy a törtrész bitek növelése javítja a felbontást, de szűkíti az ábrázolható tartományt.

8
7
FormátumQ0.7
Tartomány
Lépésköz Δ
Nyers kód q
Bináris kód
Visszaalakított x̂
Abszolút hiba
Relatív hiba

Jelölés: s = jelbit, i = egészérték-bit, f = törtrész-bit.

min
max
x
bemenet x kvantált x̂ zérus

4. Kvantálási és kerekítési hiba

A fixpontos ábrázolás a valós számokat rácspontokra vetíti. A rácspontok távolsága Δ = 2⁻F. Legközelebbi rácspontra kerekítésnél az ideális abszolút hiba legfeljebb Δ/2, amennyiben nem történik overflow vagy szaturáció.

x̂ = Q(x) e = x̂ − x legközelebbi kerekítés: |e| ≤ Δ/2 csonkolás: |e| < Δ, de a hiba torzított lehet ideálisított kvantálási zajmodell: e ~ U(−Δ/2, Δ/2) Var(e) = Δ² / 12
A Δ²/12 modell hasznos, de nem törvény. Periodikus, determinisztikus vagy visszacsatolt rendszerekben a kvantálási hiba korrelálhat a jellel. IIR szűrőkben emiatt limit cycle is kialakulhat.

Csonkolás kontra kerekítés

A csonkolás gyors, de általában torzítást visz a számításba. Audio- és mérőrendszerekben ez hallható, illetve mérhető DC-eltolódást vagy spektrális torzulást okozhat. A kerekítés számításigényesebb, de kisebb és kevésbé torzított hibát eredményez.

Felbontás kontra tartomány

Ugyanazon N bitszám mellett a törtrész bitek növelése nem ingyenes.

DöntésKövetkezmény
F növelésefinomabb Δ, kisebb kvantálási hiba, szűkebb tartomány
F csökkentésenagyobb tartomány, durvább felbontás
N növelésejobb tartomány vagy felbontás, nagyobb memória/sávszélesség/szorzóigény
A jó fixpontos formátum nem abszolút értelemben jó, hanem a jel statisztikájához és a worst-case amplitúdóhoz illeszkedik.

5. Fixpontos aritmetika: az igazi nehézség

A fixpontos számítás nem az összeadásnál, hanem a skálák követésénél válik nehézzé. A bináris pont helye minden művelet után logikailag változhat.

Összeadás és kivonás

x̂₁ = q₁ · 2−F, x̂₂ = q₂ · 2−F azonos F esetén: x̂₁ + x̂₂ = (q₁ + q₂) · 2−F eltérő F esetén előbb skálát kell egyeztetni.

Szorzás

x̂ = qx · 2−Fx ĥ = qh · 2−Fh x̂·ĥ = (qx·qh) · 2−(Fx+Fh) A szorzat törtrészbitszáma összeadódik.

Ha két Q0.15 számot összeszorzok, a nyers szorzat skálája Q0.30 jellegű lesz. Ha az eredményt újra Q0.15 formátumban akarom tárolni, akkor 15 bittel jobbra kell skálázni, lehetőleg kerekítéssel és szaturációval.

// Előjeles Q15 szorzás szemléleti pszeudokód // bemenetek: a_q15, b_q15 ∈ [-32768, 32767] int32 product_q30 = (int32)a_q15 * (int32)b_q15; int32 rounded = product_q30 + (1 << 14); // pozitív számokra egyszerű kerekítés int32 y_q15 = rounded >> 15; y_q15 = saturate_to_int16(y_q15);
Negatív számoknál a kerekítő konstans és az aritmetikai shift részletei implementációfüggő csapdákat okozhatnak. Valós rendszerben ellenőrzött, tesztelt fixpontos primitíveket érdemes használni.

Interaktív Q0.7 szorzás

8 bites, előjeles, F = 7. A termék skálája először Q14 jellegű, majd visszaskálázom Q7-re.

0.72
0.55
Kvantált x, h
Nyers egész szorzat
Visszaskálázott Q0.7 eredmény
Ideális x·h és hiba

6. Overflow: wrap-around vagy szaturáció?

Overflow akkor keletkezik, amikor az egész kód nem fér el a rendelkezésre álló bitszélességben. Két alapvető stratégia van: körbefordulás és szaturáció.

MódMechanizmusKövetkezmény
Wrap-around az eredmény modulo 2ᴺ értelmeződik gyors, de nagy amplitúdójú, nemlineáris hibát okozhat; audio- és vezérlőrendszerben veszélyes
Szaturáció az érték a min/max határra korlátozódik fizikailag gyakran értelmezhetőbb, de továbbra is nemlineáris torzítás
A szaturáció nem „pontos”, csak általában kevésbé katasztrofális. A wrap-around például pozitív túlcsordulást negatív értékké alakíthat, ami zárt szabályozási körben különösen rossz hibaalak.

Interaktív overflow-demó

A példa nyers előjeles egész kódokon fut; fixpontos számnál ugyanez történik a skálázott kódokkal.

8
Matematikai összeg
Tartomány
Wrap-around eredmény
Szaturált eredmény

7. Következmények FIR és IIR szűrőkben

FIR szűrő

FIR szűrőben a fixpontos alapművelet szorzás–összegzés. Ha a bemenet és a koefficiens is Q15, a termék Q30 skálájú. Az akkumulátornak több bit kell, mint a bemenetnek.

y[n] = Σ b[k] · x[n−k] Q15 · Q15 → Q30 M darab termék összege → guard bitek szükségesek szükséges többlet ≈ ceil(log₂ M) bit + előjel + biztonsági tartalék
// FIR Q15 szemléleti minta int64 acc = 0; for (k = 0; k < M; k++) { acc += (int32)x_q15[n-k] * (int32)b_q15[k]; // Q30 termékek } // Q30 → Q15, kerekítés + szaturáció acc += (1 << 14); y_q15 = saturate_to_int16(acc >> 15);

IIR szűrő

IIR szűrőnél a hiba veszélyesebb, mert visszacsatoláson keresztül újra belép a rendszerbe. A koefficienskvantálás elmozdítja a pólusokat, a belső állapotok kvantálása pedig önfenntartó kis oszcillációt, azaz limit cycle-t okozhat.

Én IIR fixpontos implementációnál nem elégednék meg a lebegőpontos frekvenciamenet ellenőrzésével. Vizsgálni kell a kvantált pólusokat, a belső állapotok maximális amplitúdóját, a szaturációs eseményeket és a nulla bemenetre adott hosszú idejű választ is.

Tipikus DSP-hibák

  • Nincs guard bit: az akkumulátor túlcsordul, miközben a végső kimenet még elférne.
  • Rossz shift: Q30 terméket Q15 helyett Q14 vagy Q16 skálára visznek vissza.
  • Koefficiensszaturáció: a +1.0 Q15-ben nem ábrázolható, ezért 32767 lesz, nem 32768.
  • Wrap-around szűrőben: ritka túlcsordulás is nagy spektrális torzítást okoz.
  • IIR limit cycle: nulla bemenet mellett sem tűnik el teljesen a kimenet.
  • Skálázatlan biquad: a kimenet elfér, de egy belső állapot túlcsordul.
Gyakorlati megközelítés: lebegőpontos referencia → fixpontos skálázási terv → bitpontos szimuláció → célhardveres validáció.

8. Fixpontos és lebegőpontos ábrázolás összehasonlítása

A fixpont és a lebegőpont közötti különbség nem pusztán bitszám kérdése. A fixpont állandó abszolút felbontást ad egy előre választott tartományban. A lebegőpont nagy dinamikatartományt és nagyjából relatív pontosságot ad az exponens miatt.

Fixpont: x̂ = q · 2−F q: egész kód F: rögzített törtrészbitszám Δ: állandó lépésköz
Lebegőpont: x̂ = (−1)s · significand · 2exponens s: előjel significand: mantissza/szignifikand exponens: skálázás értékenként változik
SzempontFixpontLebegőpontKritikus értelmezés
Felbontás Állandó abszolút lépésköz: Δ = 2⁻F. Az érték nagyságával változó abszolút lépésköz; közel állandó relatív pontosság. Fixpont jó, ha ismert és szűk a jeltartomány; lebegőpont jó, ha széles a dinamikatartomány.
Tartomány Erősen korlátozott, a skálázást kézzel kell megválasztani. Nagyon nagy tartomány az exponens miatt. A lebegőpont sok skálázási hibát elfed, de nem szünteti meg a kerekítési hibát.
Overflow Gyakori tervezési probléma; wrap vagy szaturáció. Túlcsordulás ritkább, de Infinity keletkezhet. Fixpontnál explicit overflow-stratégia kell. Lebegőpontnál a kivételeket és NaN-t kell kezelni.
Alulcsordulás A kis érték egyszerűen nullára kvantálódhat. Subnormal számok és fokozatos alulcsordulás lehetséges. Fixpontban a kicsi jelek elveszhetnek; lebegőpontban teljesítmény- és pontossági részletek jelentkezhetnek.
Hardver Egész ALU-val olcsó, determinisztikus, energiahatékony lehet. FPU-val kényelmes és gyors; FPU nélkül drága/lassú lehet. Hardverfüggő. Általános állításként a „fixpont mindig gyorsabb” hamis.
Programozói teher Magas: skálázás, guard bitek, rounding, saturation. Alacsonyabb, de numerikus analízis továbbra is kell. Fixpontnál a hibamodell láthatóbb, de több fegyelmet igényel.
Reprodukálhatóság Bitpontos implementáció jól kontrollálható. Fordító, FPU mód, asszociativitás és optimalizálás befolyásolhatja. Biztonságkritikus rendszerekben ez döntő szempont lehet.

9. Interaktív minitábla: ugyanazok az értékek fixpontban és Float32-ben

A táblázat a fenti Q-formátumot használja. A Float32 oszlop JavaScript Float32Array átalakítással készül. A cél nem az, hogy a Float32-t „hibátlannak” mutassam, hanem az, hogy láthatóvá váljon: fixpontban a tartományon kívüli értékek azonnal szaturálódnak vagy körbefordulnak, míg a lebegőpont sokkal szélesebb tartományban képes reprezentálni.

xfixpontos x̂fixpontos hibaFloat32(x)Float32 hibamegjegyzés

10. Gyakorlati tervezési eljárás

  1. Határozza meg a fizikai tartományt: mekkora lehet a jel maximuma és minimuma normál, illetve worst-case esetben?
  2. Válasszon előjelességet és bitszámot: előjeles kétkomplementes vagy előjel nélküli formátum?
  3. Válassza meg F-et: a tartomány még férjen el, a felbontás pedig legyen elég finom.
  4. Adjon guard biteket: különösen összegzés, FIR akkumulátor és biquad belső állapot esetén.
  5. Döntsön kerekítésről és overflow-ról: truncation/rounding, wrap/saturation.
  6. Kvantálja a koefficienseket: ellenőrizze a frekvenciamenetet, pólusokat, zérusokat.
  7. Végezzen bitpontos szimulációt: nem elég a lebegőpontos modell.
  8. Validálja célhardveren: fordító, shift, szaturáló utasítás, endianitás és integer promotion is okozhat eltérést.

Mit írok specifikációba?

Típus: signed two's complement Bitszám: N = 16 Formátum: Q0.15, F = 15 Tartomány: [-1, 0.999969482421875] Kvantálás: round-to-nearest, ties away from zero Overflow: saturate Szorzat: Q15×Q15→Q30, majd rounded shift >> 15 Akkumulátor: int64 Teszt: bit-exact referencia C/Python
A „16 bites fixpont” önmagában nem specifikáció. Legalább a fenti mezők szükségesek ahhoz, hogy két implementáció ugyanazt számolja.

11. Érdekességek és kevésbé nyilvánvaló következmények

+1 gyakran nem fér el

Q0.15-ben −1 ábrázolható, de +1 nem. A maximális pozitív érték 32767/32768.

A szaturáció nem lineáris

Ha egy szűrőben szaturáció történik, a rendszer már nem lineáris. Emiatt a szuperpozíció nem alkalmazható változtatás nélkül.

A shift kerekítése számít

A jobbra shift csonkolásként viselkedhet. Sok apró csonkolás mérhető torzítássá állhat össze.

Blokk-lebegőpont

Egyes DSP-rendszerek blokkonként közös exponenst használnak. Ez hibrid megoldás fixpont és lebegőpont között.

Dither

Kvantálás előtt kis zaj adható a jelhez, hogy a determinisztikus kvantálási torzítás zajszerűbbé váljon.

Formális bitpontosság

Beágyazott DSP-ben a referencia nem mindig „matematikai valós”, hanem egy bitpontos aranymodell.

12. Ellenőrző kérdések

Miért mondom, hogy a bináris pont nincs eltárolva?

Mert a bitminta csak egész kód. A törtrész bitek számát az értelmezési konvenció, például Q0.15, adja meg. Ugyanaz a kód más F mellett más valós érték.

Mi a különbség a kvantálási hiba és az overflow között?

A kvantálási hiba a rácsra kerekítés kis hibája, tipikusan legfeljebb Δ/2. Az overflow tartományhiba: az érték nem fér el, ezért szaturálódik vagy körbefordul. Ez sokkal durvább hiba lehet.

Miért kell több bit a FIR akkumulátorba?

Mert több szorzatot adunk össze. Még ha minden egyes szorzat el is fér, az összeg nagyobb tartományt igényelhet. Nagyságrendileg ceil(log₂ M) extra bit kell M hasonló nagyságú tag összegzéséhez.

Miért kényesebb az IIR fixpontos implementáció, mint a FIR?

Az IIR visszacsatolt. A kvantálási és kerekítési hiba visszakerülhet a rendszerbe, a koefficienskvantálás pedig elmozdítja a pólusokat. Ez stabilitási és limit-cycle problémákhoz vezethet.

Mikor választanék fixpontot lebegőpont helyett?

Ha a jeltartomány jól ismert, a hardver egész aritmetikára optimalizált, energia- vagy költségkorlát van, illetve bitpontos reprodukálhatóság szükséges. Lebegőpontot választanék, ha széles dinamikatartomány és gyors fejlesztés fontosabb.