Forum: Mikrocontroller und Digitale Elektronik Float als Int speichern


von Markus (Gast)


Lesenswert?

Hallo,

ich habe auf einem Amel eine Float-variable. Diese würde ich nun gerne 
übertragen. Da die Float nun zu groß ist, würde ich gerne das Komma 
verschieben und das ganze als Int speichern:

Also

Float:   199.99
-> Komma verschieben 199.99 * 100 = 19999
Int:     19999

Meine Frage wäre nun, welche Wege es gibt das Komma zu verschieben. Geht 
man da den Weg über die Multiplikation oder gibt es da noch andere, 
vielleich bessere Wege?

Grüße
Markus

von Phil (Gast)


Lesenswert?

Markus schrieb:
> Da die Float nun zu groß ist

Wofür zu groß? Um Sie über UART zu versenden?


Der Weg über die Mulitplikation ist sicher der einfachste.

von Markus (Gast)


Lesenswert?

Hallo,

nein, ich habe nur 64 Bit zum Versenden und da muss die Float rein und 
noch einige andere Daten. Mit der Float würde das zu viel und in zwei 
Nachrichten aufteilen geht prozesstechnisch auch nicht.

Werde dann wohl den Weg über die Multiplikation gehen.

Vielen Dank!

Grüße
Markus

von Bronco (Gast)


Lesenswert?

Markus schrieb:
> Meine Frage wäre nun, welche Wege es gibt das Komma zu verschieben. Geht
> man da den Weg über die Multiplikation oder gibt es da noch andere,
> vielleich bessere Wege?

Das hängt ganz davon ab, was Du mit dem in-Int-gewandelten Wert anfangen 
willst.
Was ist Deine Anwendung?
Soll es für Menschen lesbar sein?
Du kannst z.B. auch um 7 Bits nach links schieben (mal 128), dann hast 
Du 2 Nachkommastellen. Oder um 10 Bit schieben (mal 1024), dann hast Du 
3 Nachkommastellen.

von Karl H. (kbuchegg)


Lesenswert?

Bronco schrieb:
> Markus schrieb:
>> Meine Frage wäre nun, welche Wege es gibt das Komma zu verschieben. Geht
>> man da den Weg über die Multiplikation oder gibt es da noch andere,
>> vielleich bessere Wege?
>
> Das hängt ganz davon ab, was Du mit dem in-Int-gewandelten Wert anfangen
> willst.
> Was ist Deine Anwendung?
> Soll es für Menschen lesbar sein?
> Du kannst z.B. auch um 7 Bits nach links schieben (mal 128), dann hast
> Du 2 Nachkommastellen. Oder um 10 Bit schieben (mal 1024), dann hast Du
> 3 Nachkommastellen.

Wiedersteh aber der Versuchung einen float zu schieben.
Eine Multiplikation mit 2 ist bei einem float kein Schieben!

von Bronco (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wiedersteh aber der Versuchung einen float zu schieben.
> Eine Multiplikation mit 2 ist bei einem float kein Schieben!

Erwischt! Beim Float geht das ja gar nicht so schön einfach. Verdammt...

von Karl H. (kbuchegg)


Lesenswert?

Bronco schrieb:
> Karl Heinz Buchegger schrieb:
>> Wiedersteh aber der Versuchung einen float zu schieben.
>> Eine Multiplikation mit 2 ist bei einem float kein Schieben!
>
> Erwischt! Beim Float geht das ja gar nicht so schön einfach. Verdammt...

Und genau deswegen sollte man solche Dinge dem Compiler überlassen. Es 
ist ok, im Hinterkopf zu behalten, dass man dem µC mit 2-er Potenzen das 
Leben leichter machen kann. Aber ein

  uint16_t i = 275;

  i = i * 2;

ersetzt ein Compiler schon selbsttätig durch eine Schiebeoperation wenn 
das möglich ist.

von Pieter (Gast)


Lesenswert?

moin moin,

>>Eine Multiplikation mit 2 ist bei einem float kein Schieben!

doch, den Exp.+/- 1 ist Mod/div 2.

Float (Single) sollten jedoch 4 Byte sein und da 64Bit gesendet werden 
können passt das doch.

Wo also ist das Problem?

union float_long
{
    float f;
    long l;
};


MfG
Pieter

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Bronco schrieb:
> Karl Heinz Buchegger schrieb:
>> Wiedersteh aber der Versuchung einen float zu schieben.
>> Eine Multiplikation mit 2 ist bei einem float kein Schieben!
>
> Erwischt! Beim Float geht das ja gar nicht so schön einfach. Verdammt...

Weil floats binär aufgebaut sind, geht das recht effizient.

Wenn man nicht darauf verzichten will/kann, dann hilft ein Blick in die 
Doku von ldexpf.  Im Endeffekt addiert das ne Konstante auf den 
Exponenten und multipliziert somit den float mit einer Potenz von 2.

von Vlad T. (vlad_tepesch)


Lesenswert?

Karl Heinz Buchegger schrieb:
> uint16_t i = 275;
>
>   i = i * 2;
>
> ersetzt ein Compiler schon selbsttätig durch eine Schiebeoperation wenn
> das möglich ist.

zumal ein AVR (zumindest die Megas) schneller multipliziert als shiftet, 
zumindest bei 2^n mit n>1

von Klaus W. (mfgkw)


Lesenswert?

Pieter schrieb:
>>>Eine Multiplikation mit 2 ist bei einem float kein Schieben!
>
> doch, den Exp.+/- 1 ist Mod/div 2.
> ...

Dann darfst du aber erstens nicht die ganzen vier Byte schieben, sondern 
nur die Mantisse, zweitens zum Wandeln in eine ganze Zahl auch noch den 
bisherigen Wert des Exponenten berücksichtigen, drittens rechtzeitig das 
Vorzeichen in Sicherheit bringen und nachher wieder verwursten, und 
viertens die implizite 1 vor dem gedachten Dezimalpunkt nicht vergessen, 
und fünftens das Komma über die Mantisse nach rechts schieben.

Die Aussage:
>Eine Multiplikation mit 2 ist bei einem float kein Schieben!
... hat also schon eine gewisse Berechtigung.

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
Noch kein Account? Hier anmelden.