mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Gleitkommaberechnung


Autor: Stephan Manheimer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen an dei Spezialisten!
Habe eine Frage ich muß mehrere Integer und Long Variablen mit Float
Korrekturfaktoren multiplizieren.
Z.B. ADC Wert 532 (10bit) Referenzspannung 4.096V Faktor 102,2044
usw.
Dann kommen noch verschiedene Zeitberechnungen hinzu!
Wie kann man solche Berechnungen durchführen nur mit Int oder Long?

Autor: Uwe Nagel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Überlege dir, welcher Bruch deiner Floatzahl möglichst nahe kommt.
102,2044 ist ziemlich genau 14002/137. Also erst mit 14002
multiplizieren, dabei überlegen,ob ein Überlauf stattfinden kann und
eventuell auf 32 Bit erweitern, dann durch 137 teilen.
Eine Tabellenkalkulation kann beim suchen der Faktoren helfen.

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du näherst die float-Zahlen durch Brüche an, deren Nenner ne Potenz von
zwei ist, also z.B. 102.2044 ~ 6541/2^5. Die Division durch ne
Zweierpotenz wird durch nen einfaches Rechtsschieben des Integerwertes
realisiert. Die erreichbare Genauigkeit wird durch die Anzahl der Bits
betsimmt, die Du zur Verfügung hast.

Aus ähnlichem Grund vermutlich die Referenzspannung von 4.096V: 4096 =
2^12.

Cheers
Detlef

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn der Ausgangswert nur 10-Bittig ist, dann ist 102,2044 Mumpitz,
102,2 reicht vollkommen.

102,2 ist z.B. 511/5


Peter

P.S.:
Du weißt, daß der Endwert bei 10Bit 4,096V / 1024 * 1023 = 4,092V ist ?

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du keine Einschränkungen bezüglich des Compilers/Codegröße hast,
dann rechne mit 'float'. Du gibst den Faktor ein, den Du brauchst,
brauchst dafür nicht zu denken und keine Denkfehler zu machen.
Insbesondere, wenn Deine Faktoren variabel sind, ist es Dein Programm
dann auch.

Autor: Stephan Manheimer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnellen Antworten.
Bin relativ neu in diesem Bereich und wurde darauf hingewiesen das Flot
Berechnungen unheinlich viel Rechenzeit für einen Controller bedeuten.
Der Ratschlag war besser 5 mal Integer berechnen wie einmal Float.

Autor: Uwe Nagel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Float frisst auch viel Speicherplatz. Das ist oft schlimmer als die
Rechenzeit. Sobald eine Float-Rechnung im Programm auftaucht, wird die
Float-Bibliothek dazugelinkt, probier einfach mal aus, wieviel Platz
das kostet.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
<<wurde darauf hingewiesen das Flot
Berechnungen unheinlich viel Rechenzeit für einen Controller bedeuten.
Der Ratschlag war besser 5 mal Integer berechnen wie einmal Float.>>

Alles dummes Zeug ! Bei diesen Ratschlägen muß man zurückschlagen.

Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael, macht es Spaß, Neulinge mit solchem Mist zu verunsichern?

Tatsache bleibt:

1. Auch float-Benutzung schützt nicht vor Denkfehlern
2. Float braucht mehr Speicher und Rechenzeit als Fixkomma
3. Aufgaben der realen Welt kann man fast immer mit Fixkomma erledigen

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Philipp:
Ich mag es einfach nicht, wenn Vorurteile aus der Programmiersteinzeit
immer wieder unbewiesen behauptet werden. Für heutige µPs ist es kein
Problem mit float effektiv und schnell umzugehen. Gerade ein Anfänger
sollte lernen, die Technik zu nutzen und nicht dazu gebracht werden, im
Bitgeschupse zu ersticken.

Wer es mag, kann ja seinen Taschenrechner auf 'ganzzahlig'
einstellen, womöglich um Zeit oder Strom zu sparen; aber so blöd wird
doch niemand ernsthaft sein.

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael, float benoetigt mehr Ressourcen und ist langsamer als integer,
das ist eine Tatsache. State of the art Signalverarbeitung wie handy,
DSL etc laeuft auf integer Prozessoren, nicht auf float DSPs. Wenn Du
Strom sparen muss wg Batterie und hohe peformance in nem embedded
Geraet    brauchst ist integer die Wahl. Float kannst Du gut auf Deinem
Pentium machen, der 60W zieht oder so. Verschwendung von Ressourcen ist
ja modern, damit die Prozessorhersteller immer schnellere Prozessoren
und die Plattenhersteller immer groessere Platten verkaufen koennen,
manchmal geht das aber nicht, wenn Strom oder Platz fehlt. Wenn man
schon fette Prozessorleistung hat, kann man die auf clevere Dinge
verwenden, als sie ueber floatrechnung zu verbraten.

Cheers
Detlef

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mir scheint, du bist eher ein Theoretiker oder max. praktischer
PC-Programmierer.
In der MC-Welt hat man immer mit knappen Ressourcen zu kämpfen, es sei
denn, man überlädt sein Projekt mit Rechenmonstern. Das kann man gerne
machen, wenn es was hübsches fürs Bastelstübchen oder ein
Vorzeigeprojekt sein soll. Gehts in die Produktion und will man damit
am Ende was damit verdienen (ja, es gibt Leute, die machen das), baut
man keinen Blackfin ein, um eine Temperatur zu messen.
Ich habe schon Unmengen von Projekten realisiert, und oft genug sind
sehr zeitkritische Sachen dabei. Der Grossteil davon läuft mit Mega8
und Mega32, float habe ich noch NIE eingesetzt. Ich denke inzwischen
kaum noch nach, ob es möglich wäre, float zu benutzen.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie ich sehe, werden die Vorurteile unüberlegt wiederholt.

Nach meinen Tests auf einem ATmega mit 16 MHz brauchen eine
Multiplikation als 'long' oder als 'float' jeweils ca. 20-30µs.
Dabei werden die MUL-Befehle nicht verwendet. Bei FP wird der Code um
ca. 800 Byte erhöht.
Daß die Codegröße explodiert, oder der Prozessor in scheinbaren Schlaf
verfällt, ist bei FP nicht zu erkennen. Jeder kann sich durch eigene
Tests selbst ein Bild machen. Und der Umstand das jemand kein 'float'
braucht, kann nicht bedeuten, daß nun niemand es gebrauchen darf.

Profiprogrammierer werden sicherlich feststellen, daß Multiplikation
schneller als Division abläuft. Folgt daraus nun, daß man keine
Divisionen mehr machen darf ?

Autor: maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

ich möchte eine festkommazahl per hand einfacher umrechnen z.B:

 bsp.: 0.73

wertigkeit 2^-1  0.5    passt       in 0.73  rest 0.23     bit = 1
wertigkeit 2^-2  0.25   passt nicht in 0.23  rest 0.23     bit = 0
wertigkeit 2^-3  0.125  passt       in 0.23  rest 0.105    bit = 1
wertigkeit 2^-4  0.0625 passt       in 0.105 rest 0.0425   bit = 1

entspricht also:

0.b...

in der hexadezimalen darstellung

oder

0.1011...

in binärer darstellung.

kann ich die nachkommastellen auch mit einem taschenrechner, der
dezimal/hex/binär umrechnen kann, allerdings ohne komma, also als volle
zahl umrechnen!?
komme nicht auf die lösung...

maddin

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal ne Frage an den Spezialisten:

Warum werden die MUL Befehle denn nicht benutzt? Wo sie doch schon mal
(ebenso wie die FP-Libs) da sind und das ganze vermutlich auch
beschleunigen würden.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Warum werden die MUL Befehle denn nicht benutzt?>>

Ganz einfach, es sind LIBs für alle AVRs, die nicht alle MUL kennen.
Die Routinen laufen daher auch noch auf den AT90Sxxxx.
Könnte man mal anpassen, aber 'float' ist ja schnell genug :-)

Gibt es vielleicht auch Leute, die 'float' einsetzen und eine
Einschätzung pro/contra geben können ?
Empfehlungen von Programmieren, die das nie gemacht haben, bringen
einen doch nicht weiter.

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Maddin: die 0.73 mit 2^4 multiplizieren und dann mit nem Taschenrechner
 in binär umwandeln.

@Michael: Kein Wunder, daß Deine float MUL genauso lange dauert wie
Deine integer MUL, wenn die nativen Multiplikationsfkt. des Prozessors
nicht genutzt werden.

>>Folgt daraus nun, daß man keine Divisionen mehr machen darf ? <<
In schnellen Echtzeitanwendungen sind Divisionen, auch integer,
tödlich. Die werden mit multiplizieren/Schieben gemacht.

>>Und der Umstand das jemand kein 'float' braucht, kann nicht
bedeuten, daß nun niemand es gebrauchen darf.<<
Wehe Dir, wenn ich Dich nochmal bei ner float-Rechnung erwische!

Cheers
Detlef

Autor: maddin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
0.73 mal 16 = 11,68

11 entspricht b - scheiße - peinlich - hab mich durch die komma
rechnung allgemein total blenden lassen...

danke

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Warum werden die MUL Befehle denn nicht benutzt?

Das kann ich gar nicht glauben.

Bsp: avr-gcc, aktuelle Version, ATMega16, Optimierung auf Os

  j = 58 * i;
  aa:  89 81         ldd  r24, Y+1  ; 0x01
  ac:  9a 81         ldd  r25, Y+2  ; 0x02
  ae:  2a e3         ldi  r18, 0x3A  ; 58
  b0:  30 e0         ldi  r19, 0x00  ; 0
  b2:  82 9f         mul  r24, r18
  b4:  a0 01         movw  r20, r0
  b6:  83 9f         mul  r24, r19
  b8:  50 0d         add  r21, r0
  ba:  92 9f         mul  r25, r18
  bc:  50 0d         add  r21, r0
  be:  11 24         eor  r1, r1
  c0:  5c 83         std  Y+4, r21  ; 0x04
  c2:  4b 83         std  Y+3, r20  ; 0x03

Da wird eindeutig ein mul benutzt.
Wenn ich die Konstante mal ändere:

  j = 3 * i;
  aa:  29 81         ldd  r18, Y+1  ; 0x01
  ac:  3a 81         ldd  r19, Y+2  ; 0x02
  ae:  c9 01         movw  r24, r18
  b0:  88 0f         add  r24, r24
  b2:  99 1f         adc  r25, r25
  b4:  82 0f         add  r24, r18
  b6:  93 1f         adc  r25, r19
  b8:  9c 83         std  Y+4, r25  ; 0x04
  ba:  8b 83         std  Y+3, r24  ; 0x03

Hier optimiert der gcc, da er eine Multiplikation mit 3
durch 1 * Kopiern und 2 Additionen schneller realisieren kann.
Nach dem Muster  3 * i <==> ( i + i ) + i

Wers nicht glaubt, hier ist das komplette Program.
Der Mambo-Zambo mit der Hilfsfunktion dient nur dazu,
den Compiler an einer Constant-folding Optimierung zu
hindern:

<c>
void foo( int* a )
{
  *a = 5;
}

int main()
{
  int i;
  int j;

  foo( &i );

  j = 5 * i;

  foo( &j );

  while( 1 )
     ;
}
</c>

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach herje, Michael redet ja gar nicht von int, sondern
von long Multiplikation. Also das Ganze nochmal, diesmal mit
long:
<C>
  j = 58 * i;
  b2:  89 81         ldd  r24, Y+1  ; 0x01
  b4:  9a 81         ldd  r25, Y+2  ; 0x02
  b6:  ab 81         ldd  r26, Y+3  ; 0x03
  b8:  bc 81         ldd  r27, Y+4  ; 0x04
  ba:  bc 01         movw  r22, r24
  bc:  cd 01         movw  r24, r26
  be:  2a e3         ldi  r18, 0x3A  ; 58
  c0:  30 e0         ldi  r19, 0x00  ; 0
  c2:  40 e0         ldi  r20, 0x00  ; 0
  c4:  50 e0         ldi  r21, 0x00  ; 0
  c6:  0e 94 70 00   call  0xe0 <__mulsi3>
  ca:  dc 01         movw  r26, r24
  cc:  cb 01         movw  r24, r22
  ce:  8d 83         std  Y+5, r24  ; 0x05
  d0:  9e 83         std  Y+6, r25  ; 0x06
  d2:  af 83         std  Y+7, r26  ; 0x07
  d4:  b8 87         std  Y+8, r27  ; 0x08
</C>
Da wird tatsächlich eine Funktion aufgerufen.

Was macht die?
<C>
000000e0 <__mulsi3>:
  e0:  62 9f         mul  r22, r18
  e2:  d0 01         movw  r26, r0
  e4:  73 9f         mul  r23, r19
  e6:  f0 01         movw  r30, r0
  e8:  82 9f         mul  r24, r18
  ea:  e0 0d         add  r30, r0
  ec:  f1 1d         adc  r31, r1
  ee:  64 9f         mul  r22, r20
  f0:  e0 0d         add  r30, r0
  f2:  f1 1d         adc  r31, r1
  f4:  92 9f         mul  r25, r18
  f6:  f0 0d         add  r31, r0
  f8:  83 9f         mul  r24, r19
  fa:  f0 0d         add  r31, r0
  fc:  74 9f         mul  r23, r20
  fe:  f0 0d         add  r31, r0
 100:  65 9f         mul  r22, r21
 102:  f0 0d         add  r31, r0
 104:  99 27         eor  r25, r25
 106:  72 9f         mul  r23, r18
 108:  b0 0d         add  r27, r0
 10a:  e1 1d         adc  r30, r1
 10c:  f9 1f         adc  r31, r25
 10e:  63 9f         mul  r22, r19
 110:  b0 0d         add  r27, r0
 112:  e1 1d         adc  r30, r1
 114:  f9 1f         adc  r31, r25
 116:  bd 01         movw  r22, r26
 118:  cf 01         movw  r24, r30
 11a:  11 24         eor  r1, r1
 11c:  08 95         ret
</C>

Na also, geht doch. Wunderbare mul da drinnen

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interessant, wieviel Hellseher es hier doch gibt, die wissen, welchen MC
und welchen Compiler Stephan benutzt.


Float generell zu verdammen ist generell falsch.

Bei meinem Frequenzmesser aufm AT89C2051 benutze ich auch float.

- für 5 Digits ist die Genauigkeit ausreichend.
- für menschliche Ausgaben ist float mindestens 100 mal zu schnell.
- der Timerauslesekram ist nur wenige 100 Bytes groß, da ist noch
reichlich Platz in 2kB Flash für float (das ganze Programm benötigt
1670Byte).


Es gab also nicht den geringsten Grund float nicht zu nehmen.


Peter

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> >>Warum werden die MUL Befehle denn nicht benutzt?>>
>
> Ganz einfach, es sind LIBs für alle AVRs, die nicht alle MUL kennen.
> Die Routinen laufen daher auch noch auf den AT90Sxxxx.

Oder redest du von selbst erstellten Libraries?
Na, ja. Wenn man den Mega mit angezogener Handbremse fährt ...

Autor: Detlef _a (detlef_a)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm, Genauigkeit float/integer: Nen 32Bit float ist nicht 'genauer' als
nen 32Bit Integer. Bei ner ernsthaften Integerrechnung ist ne genaue
Betrachtung der Fehler genauso notwendig wie bei ner Floatrechnung. Die
32 Bit Floats bringen dir lediglich ne größere Dynamik als die 32 Bit
integer, die 'Genauigkeit' (dazu gehört allerdings ne Definition)
ändert sich nicht.

Cheers
Detlef

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich das 'mul long' Beispiel von Karl-Heinz auszähle, komme ich
auf etwa 40 Taktzyklen. Bei 16MHz AVR sind das dann 3,5µs.
Implementiert man 'float' mit MUL-Befehlen, reicht eine 24x24Bit
Routine, die etwas schneller sein wird, und es wird eine Skalierung des
Exponenten notwendig, sodaß ich eine 'fmul' auf ca. 5µs Schätze, wenn
sie gut codiert ist.

Greife ich den Vorschlag von Detlef_A auf (102.2044 ~ 6541/2^5), so
sieht man, daß man mit 'int' nicht mehr hinkommt, ohne einen Überlauf
zu erhalten (10 bit Wert * 6541).
Und bei dieser Optimierung wird von positiven Werten ohne Rundung des
Ergebnisses ausgegangen.

Rechnet man hingegen gleich mit 'float' reicht anstatt <Wert *
Faktor/Divisor> die einmalige Berechnung eines Skalierungsfaktors und
anschließend <Wert * Skal-Faktor>. Bei dieser Berechnung ist das
Ergebnis automatisch vorzeichenrichtig gerundet.

Ausgehend von Stephans Anforderungen rate ich weiterhin zur Verwendung
von 'float', selbst wenn er 1000 Berechnungen/s durchführen muß. Und
wenn eines Tages ein Nachfolger seine Programme warten muß, kann dieser
dann einfach die Konstante 102.2044 durch 103.3309 ersetzen, weil sich
z.B. der ADC-Eingangsbereich verändert hat.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 40 Taktzyklen

Na ja. Bei dem was der OP gepostet hat, braucht er kein long.
Da kommt er mit int locker durch. Das sind dann keine 40 Zyklen
sondern wir sind bei (ich habs nicht nachgezäht) wesentlich
weniger.

Und ob man eine float Routine in 70 bis 80 Zyklen hinkriegt
weis ich nicht. Denke aber eher nicht.

Aber im Prinzip geb ich dir recht. Wenn ich Zeit genug habe
und im Speicher nicht sparen muss dann spricht nichts gegen
float. Es sei denn man kommt mit der Rechengenauigkeit nicht hin.
Das ist aber bei einer simplen einfachen Multiplikation eher
unwahrscheinlich. Wenn die Genauigkeit bei komplexen
Berechnungen nicht reicht, dann hat man allerdings sowieso andere
Probleme als auf die Laufzeit zu achten.

Autor: Profi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ihr wisst ja: ich bin ebenfalls ein Int-Fan.
Zum Vergleich 32-bit-Int vs. 32-bit-Float:
ganz klar ist die Int-Version genauer, da hier alle Bits für das
Ergegnis zu Verfügung stehen, bei Float nur 23.

Die Kunst beim Int-Rechnen ist das Skalieren.
Tips wie:
"102,2044 ist ziemlich genau 14002/137. Also erst mit 14002
multiplizieren, dabei überlegen,ob ein Überlauf stattfinden kann und
eventuell auf 32 Bit erweitern, dann durch 137 teilen."

oder "511/5" (Tut mir leid, Peter, dass wir beide uns immer mal
wieder mal "in die Quere kommen")

bezeugen, dass der Poster sich noch ein wenig mit Zahlenformaten
beschäftigen sollte.

Die richtige Lösung lautet, wie von Autor: Detlef _A (Detlef_A) Datum:
14.09.2006 10:33 bereits vorgeschlagen:
skaliere so, dass die Wertebereiche maximal ausgeschöpt sind  und  dass
das Ergebnis in einem Format ist, mit dem man am einfachsten (möglichst
ohne Schieben) weiterarbeiten kann.

z.B. Du willst eine 10-bit gewandelte Spannung (Vref=4,096) mit vier
Nachkommastellen anzeigen, multiplizierst Du 532 (entspricht 2,1280V
max. 1023) mit 40, um auf 21280 zu kommen, und nach der ersten Stelle
schmugglest Du ein Komma in die Anzeige - na klar: bei 'gerader' Vref
braucht man nicht viel rechnen (schlechtes Beispiel).

Besseres Beispiel: Vref=3,3V  10bitADC  Faktor ist
33000/1024=32,2265625 (7 bit)
24bit-Float-Rechnung, Skalieren des Faktors mit 2^8 (ist ausreichend
genau und hat den Vorteil, dass das Ergebnis nicht geschoben wird)
32,2265625*2^8=8250
532(entspricht 532/1024*3,3V=1,714V)*8250=4389000 (10+14=24, muss also
16+16=32 bit mul sein)
4389000/256(letztes Byte abzwacken = nur mittlere 16 Bits
verwenden)=17144,53125
17144 / 10000 (Komma nach der 1.Stelle reinmalen)=1,7144 (Spannung)

Nehmen wir Dein Beispiel: Du willst mit 532 (10 bit) mit 102,2044
(eigentlich 7 Bit) multiplizieren (54372,7408). Du brauchst trotzdem 17
Bits, weil das maximale Ergebnis 1023*102,2044=104555,1012 (17 bits)
sein kann. Das ist recht ungünstig, und man sollte sich überlegen, ob
es möglich ist, den Umrechnunsfaktor auch zu skalieren, nämlich mit 0,5
, um auf 16 Bits zu kommen. Später musst Du das Ergebnis mit dem Faktor
2 korrigieren.
Wie gesagt, es kommt sehr stark auf die Aufgabe an, die man als 'ein
Ganzes' sehen muss (Wertebereiche - Genauigkeit), um zu entscheiden,
ob solche Tricks möglich sind. Auch die Wahl der Referenzspannung
spielt bei dieser Entscheidung mit eine Rolle:
Bei der ursprünglichen Aufgabe wäre eine Möglichkeit, die Vref auf
4,0076 einzustellen und mit 100 statt 102,2044 zu multiplizieren, oder
auf Vref= 3,130 und Ergebis mal 128 (ein Byte anhängen und einmal nach
rechts schieben).
Dazu braucht man alle Angaben zur Aufgabe (max. Eingangsspannung).

Wobei sich die Frage stellt, ob man die ganze Umrechnerei besser direkt
(ohne Umweg über skaliertes Zwischenergebnis) macht, anstatt bei der
Anzeigeroutine wieder mit 'durch 10 Teilen' Klimmzüge machen muss.

Ähnliche Threads:
http://www.mikrocontroller.net/forum/read-1-409044.html
http://www.mikrocontroller.net/forum/read-1-356561...
http://www.mikrocontroller.net/forum/read-1-343046.html
http://www.mikrocontroller.net/forum/read-1-288423.html

Autor: Profi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Korrigieren:
"auf Vref= 3,130 und Ergebis mal 128 (ein Byte anhängen und einmal
nach rechts schieben)."

-->
auf Vref= 2,5600V und Ergebis mal 64 (ein Byte anhängen und zweimal
nach rechts schieben).


2,128V = 532,000 bei Vref=4,0960V  532*102,2044=54372,7408
2,128V = 543,735 bei Vref=4,0076V  544*100,0000=54400,0000
2,128V = 696,189 bei Vref=3,1300V  696*128,0000=89088,0000 (Fehler)
2,128V = 849,573 bei Vref=2,5640V  850* 64,0000=54400,0000

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Profi

"oder "511/5" (Tut mir leid, Peter, dass wir beide uns immer mal
wieder mal "in die Quere kommen")"


Damit kommen wir uns doch nicht in die Quere, ist ja genau das gleiche,
was ich bereits im 4.Posting geschrieben hatte.


Peter

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Zum Vergleich 32-bit-Int vs. 32-bit-Float:
ganz klar ist die Int-Version genauer, da hier alle Bits für das
Ergegnis zu Verfügung stehen, bei Float nur 23."

@Profi:
ich stimme Dir ja in vielen Dingen zu, hier habe ich aber meine
Schwierigkeiten. In der realen Welt könnte es ja mal vorkommen, daß ein
int-Wert mit 1/82357 skaliert werden muß. Auf die Schnelle würde ich
sagen, da bleiben dann im Ergebnis nur noch 16 Bit genau.

Um ehrlich zu sein, früher habe ich die Werte auch so verschoben, um
float-Rechnerei zu sparen (8051 12MHz). Da gab es einen Sinn.
Wenn ich heute (oben) sehe, welche Tricksereien gemacht werden sollen,
um ein paar hundert Byte Code und sagen wir mal 1% CPU-Leistung
einzusparen, muß ich schmunzeln. Wenn alle Stricke reißen, kann man
immer noch optimieren. Aber ich glaube niemanden, der erzählen will,
wegen Anwendung von 'float' jemals in zeitliche Bedrängnis gekommen
zu sein, oder den Code nicht mehr in den Speicher bekommen zu haben.

@Stephan:
Sag mal Bescheid, wie Du Dich entschieden hast.

Autor: Johannes A. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Michael

Du sprichst mir aus der Seele! Ja, wo sind denn die vielen Bits
Int-Genauigkeit, wenn ich schon bei einer einfachen Konstantenformel
herumknobele, ob ich das mal-1000 noch vor dem durch-365 machen lasse
(weil genauer) oder lieber hinterher (weil besser leserlich) ...

Ansonsten breche ich jetzt mal eine Lanze für die
32bit-floating-point-Arithmethik - so schlecht ist die nämlich gar
nicht. Rückgerechnet auf 16bit integer (lassen wir mal die Kirche im
Dorf) bringt sie allemal auf 1 LSB genaue Resultate, selbst wenn man
zwischendurch durch einen >16bit-Wert teilt (82357!).

Und wer meint, für eine genaue Berechnung keine Zeit zu haben, mag sich
halt mit seinen Hausnummern herumschlagen und die mit noch mehr Aufwand
soweit egalisieren. Oder sich mal mit einer SPS beschäftigen, die ihre
Programmzyklen gar in ms zählt :)

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]
  • [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.