Festkommaarithmetik

Gast #2039566
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?
Moderator (Firma: Titel) Persönliche Seite #2039636
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
Gast #2040199
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)
Gast #2040412
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.
Gast #2044079
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren