Forum: Mikrocontroller und Digitale Elektronik wie Gleitkomma umgehen??


von Tino K. (blumengiesser)


Lesenswert?

Ich möchte folgende Formel:

float preis;
preis =   (VorKomma + NachKomma/100) * 10,6381 * 0,0649;

nicht mehr als Gleitkomma berechnen, da es so viel speicher frisst. Ich 
habe aber grad voll den Faden verloren, wie man das dann ohne Gleitkomma 
machen kann. Der Wert VorKomma kann bis 999.999 gehen. Mit dem Wert aus 
NachKomma ergibt sich eine Zahl mit 99.999.999. Das würde ja noch gehen 
aber mit der der Multiplikation mit 10.6381 (damit es keine Kommas mehr 
gibt) kommt eine doch recth große Zahl raus. Ich stehe auf dem Schlauch.

PS: Umrechnung des Gaszählerstandes (m³) in Euro

Danke!
von Mine Fields (Gast)


Lesenswert?

von Purzel H. (hacky)


Lesenswert?

preis=((100*VorKomma+NachKomma)*69041)/(100*100'000)
oder einfacher :
preis=((100*VorKomma+NachKomma)*115832) shift right 24
von Reinhard Kern (Gast)


Lesenswert?

Tino Kühn schrieb:
> Der Wert VorKomma kann bis 999.999 gehen.

Soll das heissen, der m³ Gas kostet bis zu 1 Mio Euro, oder beziehst du 
1 Mio m³? Du solltest bei Festkommaberechnungen erst mal prüfen, welche 
Zahlen überhaupt vorkommen können. Ausserdem ist eine Preisangabe in 
Euro mit 4 Nachkommastellen nicht sinnvoll.

Gruss Reinhard
von Knut (Gast)


Lesenswert?

Mega Oschi schrieb:
> preis=((100*VorKomma+NachKomma)*115832) shift right 24

nicht ganz:
preis=((uint32_t)(100*VorKomma+NachKomma)*115832) shift right 24

sonst wird der Kompiler das falsch machen...




Knut
von Simon K. (simon) Benutzerseite


Lesenswert?

Einfach in der kleinsten Einheit rechnen (z.B. Cent oder "Tausendstel 
Euro")
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Tino Kühn schrieb:
> Das würde ja noch gehen
> aber mit der der Multiplikation mit 10.6381 (damit es keine Kommas mehr
> gibt) kommt eine doch recth große Zahl raus. Ich stehe auf dem Schlauch.
Lustigerweise brauchst du entweder die Genauigkeit oder die Dynamik 
nicht. Denn eine float Zahl hat auch nur 6 signifikante Stellen!

> PS: Umrechnung des Gaszählerstandes (m³) in Euro
Euro? Geld? Abrechnung?
Siehe dort ab Abschnitt 7.6.5:
http://www.win-tux.de/c_007_005.htm#RxxobKap0070050400263A1F0121BA
1
Der Typ float ist also ungeeignet für kaufmännische und genaue wissenschaftliche Berechnungen.
;-)
von Tino K. (blumengiesser)


Lesenswert?

Danke für die Zuschriften!
Der Gaszähler kann bis 999999,999 Zählen. Die Einheit ist m³. Dies wird 
per Faktor 10,6381 in kWh umgerechnet. Der Faktor wird von den Gaswerken 
vorgegeben. Dann wird noch mit dem aktuelle Gaspreis von 0,0649 €/kwh 
multipliziert und fertig ist der Gesamtpreis oder wenn nur die delta-m³ 
gezählt werden der Zykluswert. Daher kommen die ominösen Faktoren. OK, 
das float nur 6 Nachkommastellen hat wußte ich nicht. Double macht das 
auch nicht besser, da der Mega8 30% nur durch das Einfügen der Doubl 
Variable verliert.

preis=((uint32_t)(100*VorKomma+NachKomma)*115832) shift right 24

ich glaube das geht auch nicht. Der jetzige Zählerstand ist knapp 25000 
und wenn ich das einsetze dann kommt eine Zahl größer als 32 bit raus. 
So ganz ist mir das alle snoch nicht klar...
von Ralph (Gast)


Lesenswert?

#define faktor  (uint16)((10,6381*0,0649*1024)+0,5)      ==> 707

(uint64)(Zählerstand ( in dm3 oder cm3 anstatt in m3 ) * faktor ) >> 10

Ergebnis in m3 umrechnen

(uint64) falls nötig
von Falk B. (falk)


Lesenswert?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Tino Kühn schrieb:
> OK, das float nur 6 Nachkommastellen hat wußte ich nicht.
Es geht nicht um Nachkommastellen, sondern du hast nur 6 
signifikante Stellen. Du kannst also eine Zahl wie 123456,7 nicht mehr 
zuverlässig darstellen, denn die 6 signifikanten Stellen sind schon in 
den Vorkommastellen verbraten...  :-o

Tino Kühn schrieb:
> Der Gaszähler kann bis 999999,999 Zählen.
Ändert sich also.
> Dann wird noch mit dem aktuelle Gaspreis von 0,0649 €/kwh multipliziert
Und der sowieso...
> Dies wird in kWh umgerechnet. Der Faktor wird ... vorgegeben.
Kann sich der auch ändern: andere Gasqualität, anderer Faktor?

Damit bleibt dir nichts anderes, als den vorgeschlagenen uint64 zu 
nehmen und in möglichst kleinen Einheiten zu rechnen, damit die Zahlen 
als Ganzzahl dastehen (also z.B. statt 0,0649 €/kwh in 
649centicent/kwh).
von Udo S. (urschmitt)


Lesenswert?

Warum machst du dir das Leben unnötig schwer indem du erst die riesigen 
Absolutzahlen umrechnest. Dich interessiert nur der Verbrauch, also ERST 
die Differenz aus den Zählerständen, damit ist deine Zahl 
realistigerweise schon mal deutlich kleiner als 6 Stellen.
Wenn du beliebig genau rechnen willst, dann solltest du dir BCD codierte 
(bei µC ggf. gepackt codierte) Zahlen anschauen. Algorithmen für die 
Grundrechenarten findet man garantiert im Netz, ansonsten ist das eine 
gute Übung.
von Reinhard R. (reinhardr)


Lesenswert?

Realistischerweise ist der Zählerstand vielleicht um eine Größenordnung 
größer als die Differenzen, er läuft ja nicht seit der Jungsteinzeit ;). 
Man spart sich also nicht viel indem man mit Differenzen rechnet.

Ich würde das oben erwähnte Verfahren auf einen 32bit shift aufblasen, 
dann sollte man mit den signifikanten Stellen einigermaßen auskommen.

1
#define faktor (uint32_t)((10,6381 * 0,0649 * 4294967296) + 0,5) // ~2,97e9
2
3
zaehlerstand_100 = (100 * vorkomma) + nachkomma;
4
5
preis_cent = (uint64_t)(zaehlerstand_100 * faktor ) >> 32;

Technisch gesehen erscheint es bizarr wegen so einem Problem mit einem 
64bit Integer zu rechnen, immerhin dürfte die Genauigkeit des Zählers um 
Größenordnungen schlechter sein, aber der Buchhaltung wird es trotzdem 
auffallen wenn man es nicht macht.

Gruß,
Reinhard
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Udo Schmitt schrieb:
> realistigerweise
Das ist ein schönes Wort... ;-)
von Reinhard R. (reinhardr)


Lesenswert?

Das hatte ich ganz überlesen. So gesehen könnte man in mein Posting eine 
spöttische Note rein interpretieren (gleiche Wortwahl, etwas 
unterschiedliche Aussage), die so nicht beabsichtigt war.
von Udo S. (urschmitt)


Lesenswert?

Lothar Miller schrieb:
> Udo Schmitt schrieb:
>> realistigerweise
> Das ist ein schönes Wort... ;-)
Uuups, wohl wahr, den hatte ich verdient :-)
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.