Forum: Mikrocontroller und Digitale Elektronik Unterschiedliche Ergebnisse bei float und long


von Juri (Gast)


Lesenswert?

Hallo!

Hab folgende Codezeilen:
1
  
2
float one_ticks;
3
unsigned long clk;
4
unsigned char divider;
5
unsigned long ticks;
6
unsigned long time_us;
7
8
....
9
10
one_ticks = (float) (((float)divider) / ((float) clk)); //seconds
11
one_ticks = one_ticks * 1e6; //µs
12
ticks = (unsigned long)(time_us / one_ticks);

Nicht schön, aber funktioniert.

Nun wollte ich den Code optimieren und vor allem mit integer/long 
rechnen.
Die einzelnen Rechenschritte zusammengefasst sieht dann theoretisch so 
aus:
1
ticks = (unsigned long) ((time_us * clk) / (divider * 1e6));

Aber funktionieren tut's nicht! - Was mache ich falsch?
Wie optimiere ich richtig?

Danke für eure Hilfe.

Gruß
Juri

von Ingo L. (Gast)


Lesenswert?

Und was geht nicht?

von Juri (Gast)


Lesenswert?

Es kommt einfach ein anderes Ergbnis raus.
Die float-Funktion liefert z.B 5000 zurück, die long-Version 162.

Das ganze läuft übrigens auf einem MSP430F2418.

von egbert (Gast)


Lesenswert?

Du verwendest offensichtlich etwas, was fälschlicherweise als 
Programmiersprache bezeichnet wird, jedoch aufgrund der uneindeutigen 
und meist compilerabhängigen Sprachdefinition bzw. Implementation mehr 
oder weniger zufällige Ergebnisse liefert. Diesen "C"-Quatsch sollte man 
nur verwenden, sofern einem langweilig oder das Ergebnis egal ist. 
Benutze besser eine richtige bzw. professionelle Programmiersprache, 
dann must Du dich nicht mit solchem Kinderkram herumschlagen.

Gruß,
Egbert

von Juri (Gast)


Lesenswert?

Was ist denn das für eine Antwort!?!?

von Floh (Gast)


Lesenswert?

egbert schrieb:
> Benutze besser eine richtige bzw. professionelle Programmiersprache,
Beispielsweise?

von (prx) A. K. (prx)


Lesenswert?

Juri schrieb:

> (divider * 1e6)

Auf diese Art wirst du Fliesskommarechnung aber nicht los.

von Juri (Gast)


Lesenswert?

Floh schrieb:
> Beispielsweise?

Das habe ich mich auch gefragt.

A. K. schrieb:
> Auf diese Art wirst du Fliesskommarechnung aber nicht los.

Wegen dem "1e6"!? Soll ich dann lieber 1000000 schreiben?

von (prx) A. K. (prx)


Lesenswert?

Korrekt erkannt.

von Peter II (Gast)


Lesenswert?

unsigned char divider;
(divider * 1e6));

das pass aber nicht in ein unsigned char

besser sollte es so sein:

(divider * 1e6ul));

von temp (Gast)


Lesenswert?

Wenn wir dem egbert alles wegnehmen was in C geschrieben ist, kann er 
wieder mit dem Brummkreisel spielen. Und so einen Mist schreiben kann er 
dann auch nicht mehr.

von (prx) A. K. (prx)


Lesenswert?

Juri schrieb:

>> Beispielsweise?
>
> Das habe ich mich auch gefragt.

Er meint T/PL, auch bekannt als Troll Programming Language.

von (prx) A. K. (prx)


Lesenswert?

Peter II schrieb:

> (divider * 1e6ul));

War das nicht 1uL6? ;-)

von Juri (Gast)


Lesenswert?

Zurück zu meinem Problem:
Dieses befand sich zwischen Tastatur und Stuhllehne.
Wenn time_us = 5.000 und clk = 8.000.000 (Punkt = 1000er Trennzeichen) 
hat man bei der Berechnung von
(time_us * clk) eigentlich das Ergebnis von 40.000.000.000 . Das passt 
aber in einen unsigned long mit 2^32-1=4.294.967.295 nicht rein. 
Überlauf, anderes Ergebnis...

Ein wenig umgestellt, um die Wertebereiche einzuhalten und schon 
funktionierts:
1
ticks = ((clk/1000000)*time_us)/divider

von Juri (Gast)


Lesenswert?

A. K. schrieb:
> Er meint T/PL, auch bekannt als Troll Programming Language.

Wo kann man die lernen? ;)

von Karl H. (kbuchegg)


Lesenswert?

Juri schrieb:
> A. K. schrieb:
>> Er meint T/PL, auch bekannt als Troll Programming Language.
>
> Wo kann man die lernen? ;)

Die muss man nicht lernen. Das ist ja das Geniale daran.

von Karl H. (kbuchegg)


Lesenswert?

Juri schrieb:

> Ein wenig umgestellt, um die Wertebereiche einzuhalten und schon
> funktionierts:
>
1
ticks = ((clk/1000000)*time_us)/divider

Das Problem könnte jetzt höchstens noch sein, dass du bei clk/1000000 zu 
viel verlierst. Bei deinen 8Mio geradeaus ist das kein Problem. Bei 
anderen Frequenzen mag das aber zu einem werden. Dann müsste man zb mal 
untersuchen, ob man nicht die Division auf 2 mal aufteilt

Ala
1
  ticks = ((clk/1000)*time_us/1000)/divider;

Reine Mathematik hat mit den realen Gegebenheiten in einem Computer 
manchmal nur wenig zu tun.

von Willi (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
>> Wo kann man die lernen? ;)
>
> Die muss man nicht lernen. Das ist ja das Geniale daran.

Köstlich!

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.