Hallo, ich habe grade einen grossen hänger. ich möchte z.b diese Zahlen multiplizieren 4095 * 2.1 = ? mit Fließkommamultiplikation dauert das so um die 350 Zyklen. das ist zu lang. Möchte das ganze mit fractional lösen. So laut diverser Quellen liegt der Zahlenbereich von fractional von 1 bis -1. Soweit ok. nehme meine 4095 teile sie durch 32768 und hab die entsprechende fractionalzahl. wie kann ich die jetzt mit 2.1 multiplizieren ? Mein mC kann entwerder fractional- oder integermode, ( wobei 2.1 kein integer ist ) ich habe mir selber 2 Ansätze überlegt. entweder mach ich aus dem 1.15 format zb ein 4.12 format oder ich teile die 2.1 auch durch 32768 und multipliziere das ergebnis mit 32768². Bei der zweiten Methode werden werden aber meine Register zu kurz sein, denn ich muss ja eine 16bit zahl mit einer 32 bit Zahl multiplizieren ka ob das geht. Wie gesagt mein Problem ist, dass alle Quellen die ich zu diesem Thema gelesen habe von einem 1.15 format ausgehen. Auch habe ich diverse beispielcodes für PID Regler oder FIR_Filter die ebenfals von einem 1.15 Format ausgehen. grade beim PID Regler muss aber eine Zahl mit einer anderen Zahl grösser 1 multiplizieren können . Es kann sein das ich fractional total falsch verstanden hab. Habe ich warscheinlich auch. Es ist doch so das bei einem 1.15 Format also eine Stelle vor dem Komma und 15 stellen nach dem Komma (bzw das Bit vor dem Komma ist das Vorzeichenbit) die Stellenwertigkeit = 2¯¹ ,2¯²,2¯³...... ist ? naja,Ich hoffe das man Problem verstehen kann und das ich hier hilfe bekomme.
> 4095 teile sie durch 32768 und hab die entsprechende fractionalzahl. > wie kann ich die jetzt mit 2.1 multiplizieren ? Ich würde lieber die 2.1 in eine fixed point Zahl umwandeln und dann mit 4095 multiplizieren. Jetzt ist halt die Frage wie genau du das brauchst. Die 0.1 lassen sich nicht so genau darstellen und um so genauer du es brauchst, um so mehr Bits must du spendieren. Also mal angenommen anstatt 0.1 währe 0.125 möglich -> 1/8. Dann könntest du 2.125 mit U(2,3) darstellen. U steht für unsigned, 2 integer Bits und 3 fraktionale Bits. Um 2.125 in das Format umzuwandeln, must du die Zahl mit 2^3 multiplizieren. -- Das ist die Anzahl an fraktionalen Bits --. 2.125 * 2^3 = 17 Um das mal zu verdeutlichen 17 -> b10.001 Die Wertigkeit ist 2^1 2^0 . 2^-1 2^-2 2^-3 Die 17 kannst du jetzt mit 4095 multiplizieren, musst aber noch eine Berechnung durchführen, was dein Ergebnis dann nacher bedeutet. 4095 kann mit 12 Bit unsigned dargestellt werden, in fixed point Notation U(12,0). Die fixed point Regel besagt jetzt für unsigned Multiplikation: U(a1,b1) * U(a2,b2) = U(a1+a2,b1+b2) Also U(12,0) * U(2,3) = U(14,3) Zur Berechnung: 4095 * 17 = 69615 Wenn du jetzt wissen willst was das Ergebnis für einen floating point Wert darstellt, teile das Ergebnis einfach durch 2^3. 69615 / 2^3 = 8701,875 Das ist auch genau was 4095 * 2.125 ergibt.
Hi vielen Dank für dein Post, hat mir super weitergeholfen.
Hallo, das angegebene Beispiel kann ich auf mein Problem nicht anwenden. Ich habe einige Quellen dazugelesen und ich verstehe das immer noch nicht. Ist das so schwer oder übersehe ich etwas. Ich fand folgende Quellen informativ: http://www.acoustics.hut.fi/teaching/S-89.3510/2006/projektityo/FixedPointDSPDev.pdf http://www.digitalsignallabs.com/fp.pdf Diese haben mich nicht weitergebracht. Was ich machen will, ist, FIR-Filter, die kleiner +1 und größer sind -1 in fixed-point darstellen und multiplzieren. Z.B. coef=-0.2345, sample=4095 res=-0.2345*4095=-960.2775 danach kommt eine Addition des vorherigen Wertes. Kann mir da jemand weiterhelfen? Danke!
>>Z.B. coef=-0.2345, sample=4095 >>res=-0.2345*4095=-960.2775 Du skalierst Deinen Coeffizienten: -0.2345 = -61473/2^18 Also 4095*-61473 rechnen und dann durch 2^18teilen, indem man das Ergebnis 18 Stellen nach rechts schiebt, Ergebnis ist -960. Die verfügbare Bitzahl bestimmt die Genauigkeit: 4095 sind 12Bit, 61xxx sind 16Bit, multipliziert gibt das 28, 1 fürs Vorzeichen und bißchen Reserve. Für nen ganz groben Hack könnte man die 4095 auch einfach 2 Bit rechtsschieben, dann hieße der Coeffizient 0.25. Gute Nacht Detlef
Hi, danke für die Antwort. Ich habe da noch ne Frage. Was mache ich, wenn ich nur 16-bit für das Ergebnis zur Verfügung habe. Kann ich nicht das Ergebnis in 16-Bit mit Bitverschiebung darstellen? Was ich machen will, ist, zwei short (16-bit) Variablen zu multiplizieren. Das Ergebnis soll dann auch short sein. Noch was zur Theorie: Ich habe gelesen, dass bei der Integer-Multip. von ANSI Standard (16x16=32) die untere Hälfte des Ergebnisses aus der Multipl. erhalten bleibt, während in der Fixed-Point-Arithmetik die obere Hälfte erhalten bleibt. Kann mir das jmd erklären, wie ich an die obere Hälfte rankomme? Mit Zahlenbeispiel bitte. Danke nochmal!
DSPNeuling wrote: > Was ich machen will, ist, zwei short (16-bit) Variablen zu > multiplizieren. Das Ergebnis soll dann auch short sein. > Das Ergebnis ist 16 Bit lang. Eine 16Bit Zahl mit einem Koeffizienten betragsmäßig kleiner 1 multipliziert ergibt wieder 16 Bit Ergebnisse. Das Zwischenergebnis vorm schiben ist länger, 16Bit*16Bit =32 Bit. >Ich habe gelesen, dass bei der Integer-Multip. von > ANSI Standard (16x16=32) die untere Hälfte des Ergebnisses aus der > Multipl. erhalten bleibt, während in der Fixed-Point-Arithmetik die > obere Hälfte erhalten bleibt. Die Frage verstehe ich nicht. > Noch was zur Theorie: 'Grau ist alle Theorie und grün des Lebens goldner Baum' Cheers Detlef
Hi Detlef, <Das Ergebnis ist 16 Bit lang. Eine 16Bit Zahl mit einem Koeffizienten <betragsmäßig kleiner 1 multipliziert ergibt wieder 16 Bit Ergebnisse. <Das Zwischenergebnis vorm schiben ist länger, 16Bit*16Bit =32 Bit. (4095*-61473)/2^18 = -960 Steht das Ergebnis in MSB oder LSB? Das ist oben meine Frage gewesen? Wird MSB oder LSB ausgegeben? Ergebnis ist 28 bit, hattest du geschrieben. Wie kann ich das jetzt auf 16 Bit reduzieren? Und warum skalierst du mit 18 und nicht mit 15? Wenn ich nur 15 bits zur Verfügung habe? Irgendwie verstehe ich das immer noch nicht :-( Ich will das verstehen.
Rechnung mal genau, allerdings ohne negatives Vorzeichen: 4095*61473=251731935 Jetzt im hexadezimalen Zahlensystem (0x ist der Präfix für hex-Zahlen) 0xfff*0xf021=0xf011fdf LSB/MSB kann least/most significant Bit oder Byte heißen, das spielt aber keine Rolle. Nach der Mutiplikation hat das Ergebnis 0xf011fdf 28 Bit. Die oberen 12Bit (das HighWORD) ist 0xf01, das lowword 0x1fdf ist 16Bit lang. Die 28 Bit passen in ein 32 Bit Wort rein. Jetzt kommt das Teilen durch 2^18. Teilen durch 2 macht man durch Schieben des 32 Bit Wortes um eine Stelle nach rechts: 0xf011fdf >>1 = 0x7808fef Das Ergebnis hat nur noch 27Bit. Das insgesamt 18Mal machen (/2^18) läßt 10Bit übrig, die passen wieder in ein 16Bit Wort. Für das Ergebnis der Multiplikation braucht man aber die 32Bit. >>nd warum skalierst du mit 18 und nicht mit 15? 32Bit brauch ich sowieso, wenn ich mit 15 skaliere statt mit 18 verschenke ich ohne Not Genauigkeit. >>Ergebnis ist 28 bit, hattest du geschrieben. Wie kann ich das jetzt auf >>16 Bit reduzieren? Schieben, 18 Mal nach rechts. >>Ich will das verstehen. Finde ich gut ! Cheers Detlef
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.