www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Festkommaarithmetik


Autor: Yonas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Yonas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich werde mir das mal genauer anschauen, DANKE.

Autor: df1as (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Sym (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Yonas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Zwölf Mal Acht (hacky)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Yonas (Gast)
Datum:

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

Autor: Yonas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ach sorry so ein schmaren von mir!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.