Forum: FPGA, VHDL & Co. Festkommaarithmetik


von Yonas (Gast)


Lesenswert?

Hallo zusammen,

ich versuch gerade mir das rechnen mit Festkommazahlen bei zubringen, 
nun meine Frage. Nehmen wir an ich hab ein Festkommazahl 1Q2 und zwar 
signed.

Also
uint16  bin  Dez
   0    000  0
   1    001  0.25
   2    010  0.5
   3    011  0.75

   4    100  -1
   5    101  -.075
   6    110  -0.5
   7    111  -0.25

nun z.B 0.25 * 0.75 --> Dez 0.1875 --> uint16 1*3 = 3 dezimal 
interpretiert also (3*3)bit = 6Bit also

   00,0011 --> 0.1875 also richtig
allerdings schlägt die Methode beim Multiplikation mit Negative Zahlen 
fehl

z.B   -0.75 * 0.5 = -0.375  --> uint16 7*2 = 14 -->  00,1110

wie muss ich mir denn das multiplizieren mit Negative Zahlen vorstellen?
oder muss ich mir das vorzeichen vormerken und weiter wie oben mit den 
Positive Zhalen verfahren?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Yonas schrieb:
> wie muss ich mir denn das multiplizieren mit Negative Zahlen vorstellen?
Die Gegenfrage ist: wie stellst du dir eine "normale" 
Integer-Signed-Multiplikation vor?
Nimm mal deine 3-Bit-Zahl und teil sie nicht durch 4:
uint16  bin  Dez
   0    000  0
   1    001  1
   2    010  2
   3    011  3

   4    100  -4
   5    101  -3
   6    110  -2
   7    111  -1

3 * 1 = 3 = 011
Wie machst du da eine signed-Multiplikation?
-3 * 1 = 5*1 = 101 = -3
Und was passiert bei -3*2, so wie du es da oben gemacht hast?
-3 * 2 = 5*2 = 1010 = ???
Ein Überlauf! Der Zahlenbereich ist nicht ausreichend weit definiert!

Und dein Fixpunktformat 1Q2 ist erstmal nichts anderes, wie eine 
ordinäre Integerzahl, die dann zur Interpretation einfach durch 4 
geteilt wird.

Du hast also zuerst das Problem, dass du mit deinem Zahlenbereich das 
zwar noch darstellen kannst:
> uint16 1*3 = 3
Das aber nicht mehr:
> uint16 7*2 = 14 -->  00,1110
Rechne mal exemplarisch
uint16 2*3 = ?
was kommt raus?

Sieh dir das mal an:
http://mandalex.manderby.com/i/integerarithmetik.php

von Yonas (Gast)


Lesenswert?

ich werde mir das mal genauer anschauen, DANKE.

von df1as (Gast)


Lesenswert?

Bei Punktrechnungen musst du für beide Eingangsgrößen den Absolutbetrag 
bilden (und merken, wie oft dazu negiert werden musste). Das Ergebnis 
hieraus wird, wenn eine ungerade Anzahl an negativen Eingangsgrößen 
vorlag, am Ende negiert.


Beispiel 0,25 * -0,5:

0.01 * 1.10 |  1 (0,25) * 6 (-0,5)
0.01 * 0.10 |  1 (0,25) * 2 ( 0,5) 1-mal wurde negiert
------------+---------------------
00.0010     |  2 ( 0,125)          muss negiert werden
11.1110     | 62 (-0,125)


Beispiel -0,75 * -0,5:

1.01 * 1.10 |  5 (-0,75) * 6 (-0,5)
0.11 * 0.10 |  3 ( 0,75) * 2 ( 0,5) 2-mal wurde negiert
------------+----------------------
00.0110     |  6 ( 0,375)           muss nicht negiert werden


Sinvoller Weise wählt man für ein Produkt aus zwei 3-Bit-Zahlen 6 Bit. 
Die Anzahl Nachkommastellen addiert sich (2 + 2 = 4). Die Stellenzahl 
kann wegen des Wegfalls der Vorzeichen beim Zwischenergebnis nicht 
weiter verkleinert werden (wg. der kleinsten negativen Zahl bzw. der 
0-Asymmetrie beim 2er-Komplement).

Größtes Ergebnis bei -1,00 * -1,00 = 1,00 (01.0000)

von Sym (Gast)


Lesenswert?

Eine signed Multiplikation ist nicht gleich mit einer unsigned 
Multiplikation. Du musst dem Compiler vorher mitteilen, wie er die Zahl 
zu interpretieren hat. Ob du nun mit fixed point oder reinen Integern 
arbeitet macht keinen Unterschied abgesehen vom Schieben nach der 
Multiplizieren.

Wie du erkannt hast, macht es bei der Addition, Subtraktion im 
twos-complement Format keinen Unterschied.

von Yonas (Gast)


Lesenswert?

jetzt mal eim ganz blöde Frage, wie bekomme ich nach eine Multiplikation 
auf die kommazahlen? die zweite Frage ist, Wenn man normalisiert hat (-1 
bis 0.9999) und -1 * -1 = 1 was macht man denn jetzt mit der 1 ? denn 
das grösste Positive zahl ist ja 0,99999.

von Purzel H. (hacky)


Lesenswert?

>was macht man denn jetzt mit der 1 ? denn das grösste Positive zahl ist ja 
0,99999.

vorher durch 10 teilen.

Man macht die fixkomma Rechnung normalerweise nicht so streng. Ich 
rechne teilweise mit Zehnteln, oder Vierundsechzigsteln, oder so.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Yonas schrieb:
> -1 * -1 = 1 was macht man denn jetzt mit der 1 ?
Pech gehabt. Sowas nennt man Überlauf. :-o
Das sollte vor der Operation abgefragt werden...

von Yonas (Gast)


Lesenswert?

Warum denn durch 10 teilen, ich würde durch 2 teilen das reich doch auch 
oder?

von Yonas (Gast)


Lesenswert?

ach sorry so ein schmaren von mir!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.