Konvertierung von double in integer

Persönliche Seite #5783535
Lesenswert?

Felix E. schrieb:
> Programmiere einen ESP8266 also arduino basiert

"Also"? Den könnte man auch mit irgendwas anderem programmieren.

Wie auch immer, es geht also um C++.


> Sollte genau gerundet sein!

Dann vor dem Typecast 0.5 addieren.

Der Typecast schneidet ab.
1
double x = 1234.56;
2

3
int y = x;
4

5
int z = x  + 0.5;
6

7
printf("y = %d  z = %d\n", y, z);

Resultat:

y = 1234  z = 1235
Gast #5783745
Lesenswert?

Felix E. schrieb:
> ich denke mein Anliegen ist klar,

Nein, dein Anliegen ist durchaus nicht klar. Wozu ein double bemühen, 
wenn man's anschließend auf einen int herunterbrechen will?

Also, wenn man PI so rundet, dann fällt man weit hinter die alten 
Ägypter zurück, die konnten das schon besser als nur 3.

Und was wird aus 1.735E37 werden?

Also, erstmal glaube ich nicht, daß man für solche Feld-Wald-Wiese 
ausgerechnet double braucht, das rechnet sowieso kaum ein billiger µC in 
Hardware (ob der ESP8266 das etwa in HW kann?) und zweitens wäre dann 
allenfalls ein int64 oder notfalls ein long angesagt.

Besser für Meßzwecke wäre es allerdings, einfach float als single zu 
nehmen und dann auch in float zu bleiben.

Also: wozu soll's denn gut sein?

W.S.
#5783775
Lesenswert?

Markus F. schrieb:
> So rundet da nix, da wird bloß abgeschnitten.
>
> So geht's richtig:
>
>
1
>     double x;
2
> 
3
>     int a = (x > 0.0 ? (int) (x + 0.5) : (int) (x - 0.5));
4
>

Gibt es einen tieferen Grund, warum hier alle das Rad neu erfinden? Die 
Funktion round() aus der libm existiert, ist standardisiert und tut 
exakt das verlangte. Im Zweifelsfall ist sie auch effizienter als 
jedes Eigengewächs.
OP #5783780
Lesenswert?

W.S. schrieb:
> Also: wozu soll's denn gut sein?

Daten eines MPU6050 werden erfasst und umgerechnet auf grad bzw. auch 
ein komplementärfilter verwendet um das driften zu minimieren. Nun 
möchte ich die entgültigen beschleunigungsdaten in int umwandeln um sie 
danach über mqtt zu publishen, und eben die kommastellen beim empfänger 
nicht mehr benötige und das dann nur unnötig genaue daten wären, jedoch 
brauche ich für die berechnungen die kommastellen um das ergebnis so 
genau wie möglich zu halten
Moderator #5783810
Lesenswert?

Axel S. schrieb:
> Gibt es einen tieferen Grund, warum hier alle das Rad neu erfinden? Die
> Funktion round() aus der libm existiert, ist standardisiert und tut
> exakt das verlangte.

Ich verstehe auch nicht, warum deine beiden Beiträge (und anfangs auch
Dirks Beitrag) abgewertet worden sind. Noch besser als round ist in
diesem Fall nur lround, da dieses die Konvertierung nach long bzw. int
(was auf dem ESP8266 dasselbe ist) bereits integriert hat, was die
Funktion evtl. noch etwas schneller macht.

Also:

1
  a = lround(x);
#5783891
Lesenswert?

Yalu X. schrieb:
> Axel S. schrieb:
>> Gibt es einen tieferen Grund, warum hier alle das Rad neu erfinden? Die
>> Funktion round() aus der libm existiert, ist standardisiert und tut
>> exakt das verlangte.
>
> Ich verstehe auch nicht, warum deine beiden Beiträge (und anfangs auch
> Dirks Beitrag) abgewertet worden sind.

Haha. Dirk habe ich wieder auf 0 hoch gevotet.

Sind wohl zuviele Kasper mit Accounts (und deswegen dem Recht zu voten) 
unterwegs. Wenn ich daran denke daß das womöglich die Menschen sind die 
übernehmen, wenn ich mal in Rente gehe, dann wird mir ganz anders.
#5783958
Lesenswert?

Axel S. schrieb:
> Gibt es einen tieferen Grund, warum hier alle das Rad neu erfinden? Die
> Funktion round() aus der libm existiert, ist standardisiert und tut
> exakt das verlangte.

Natürlich kann man auch round() verwenden. Und sollte das auch tun, wenn 
man sowieso die libm einbinden muß.

Wenn ich aber nur eine einzige Zeile brauche, um ganz ohne Library klar 
und verständlich hinzuschreiben, was ich will, dann spare ich mir das. 
Der Compiler kann (ohne LTO-"Tricks") inlinen und im besten Fall spare 
ich einen Funktionsaufruf.

Kann jeder halten, wie er will. Jetzt weiß der TO hoffentlich 
wenigstens, was round() tut.
Gast #5783963
Lesenswert?

Markus F. schrieb:
> klar und verständlich hinzuschreiben, was ich will, dann spare ich mir
> das.

Du findest also so eine Formel verständlicher als "round"? Jeder 
Programmierer, der round sieht, weiß sofort was gemeint ist. Eine Formel 
zu entschlüsseln dauert auf jeden Fall länger.
#5784311
Lesenswert?

Markus F. schrieb:
> Axel S. schrieb:
>> Gibt es einen tieferen Grund, warum hier alle das Rad neu erfinden? Die
>> Funktion round() aus der libm existiert, ist standardisiert und tut
>> exakt das verlangte.
>
> Natürlich kann man auch round() verwenden. Und sollte das auch tun, wenn
> man sowieso die libm einbinden muß.

Warum diese Einschränkung? Gibt es Geld zurück für die Nichtverwendung 
von Bibliotheksfunktionen?

Zum zweiten Punkt hat Dr. Sommer sich ja schon geäußert:

Dr. Sommer schrieb:
> Markus F. schrieb:
>> klar und verständlich hinzuschreiben, was ich will, dann spare ich mir
>> das.
>
> Du findest also so eine Formel verständlicher als "round"? Jeder
> Programmierer, der round sieht, weiß sofort was gemeint ist. Eine Formel
> zu entschlüsseln dauert auf jeden Fall länger.

Wahrscheinlich stopft er das dann selber in eine Funktion und nennt sie 
my_round() (weil nur round() geht ja nicht, da könnte es zu Konflikten 
kommen, falls libm für was anderes dazugelinkt wird)
Moderator #5784350
Lesenswert?

Markus F. schrieb:
> Wenn ich aber nur eine einzige Zeile brauche, um ganz ohne Library klar
> und verständlich hinzuschreiben, was ich will, dann spare ich mir das.
> Der Compiler kann (ohne LTO-"Tricks") inlinen und im besten Fall spare
> ich einen Funktionsaufruf.

Auf einem Prozessor ohne FPU wie dem ESP8266 benötigt

1
(int)(x>0.0 ? x+0.5 : x-0.5)

3 direkte Funktionsaufrufe (Vergleich, Addition/Subtraktion und Cast),

1
(int)round(x)

2 direkte Funktionsaufrufe (round und Cast) und

1
lround(x)

1 direkten Funktionsaufruf (lround).

Es sind aber nicht nur die Funktionsaufrufe selbst, an denen Zeit
gespart werden kann. Man kann davon ausgehen, dass die aufgerufenen
FP-Funktionen intern auf Assembler-Ebene sehr gut auf ihre jeweilige
Aufgabe hin optimiert sind. Je spezifischer diese Aufgabe ist, umso
besser ist i.Allg. auch die Optimierung. So muss bspw. in round nicht
nach positivem oder negativen Vorzeichen unterschieden werden, da in der
internen Darstellung die FP-Zahl bereits getrennt nach Betrag und
Vorzeichen vorliegt. In lround muss auch nicht explizit nach int bzw.
long gecastet werden, da das in einem Aufwasch mit der Bestimmung des
ganzzahligen Anteils erfolgen kann.

Somit dürfte die zweite Variante deutlich schneller als die erste und
die dritte deutlich schneller als die zweite sein.

Vielleicht hat ja jemand Lust, die Laufzeiten der drei Varianten auf
einem ESP8266 zu messen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren