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.
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.pdfhttp://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