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!
preis=((100*VorKomma+NachKomma)*69041)/(100*100'000) oder einfacher : preis=((100*VorKomma+NachKomma)*115832) shift right 24
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
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
Einfach in der kleinsten Einheit rechnen (z.B. Cent oder "Tausendstel Euro")
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. |
;-)
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...
#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
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).
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.
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.