Wie funktioniert Konvertierung von double zu int?
-
berniebutt schrieb:
Ein Programm muss zuverlässig laufen.
Genau da hängts doch mit double
-
Aaaalso:
Die Anwendung ist von mir selbst geschrieben worden - damals in C. Ein einigermassen aufwendiges Konsolenprogramm mit Eingabemasken und so weiter. Da die Windows-Konsole nicht mehr 100%ig der damaligen DOS-Konsole entspricht, ich aber beim Jahrtausendwechsel noch mal 'dran musste', sind mittlerweile einige wenige Dinge drin, die sich ein paar Vorteile von C++ zu Nutze machen - es ist aber bei weitem kein C++ - Programm.
In der Zwischenzeit habe ich mal begonnen, eine Klasse für BCD-Zahlen zu schreiben, beim Dividieren habe ich's glaube ich erst Mal einstellen müssen ... aber in meiner Anwendung würde subtrahieren und addieren auch genügen. Da ich aber nur zwei Nachkommastellen habe, genügt mir eine Konvertierung in Integer vor Addition/Subtraktion; das ist auf jeden Fall um Längen einfacher, als nun in allen relevanten Programmteilen den Datentyp auszutauschen. Naja - eigentlich war meine Ursprungsfrage ja, wie wird (vom Compiler) die Umwandlung durchgeführt, da es ja den Anschein macht, daß eben nicht einfach abgeschnitten wird, sondern gerundet, was für mich die zweite Überraschung (nach den Genauigkeitsproblemen der Fließkommazahlen vor ein paar Jahren) ist.
Ja - und ich habe eben gelernt, daß es weniger umständlich geht, als ich es angegangen bin (Stichwort: Addition eines geeigneten Epsilon-Wertes).
-
berniebutt schrieb:
@An Alle: Mannomann - wenn wir Oldie-Programmierer uns mit den seinerzeit schlechteren Compilern um solchen Kleinkram gekümmert hätten, wäre kein Programm gelaufen. Was macht ihr da heute?
Ich nehm absichtlich ein einfaches Beispiel, das unter MSVC 2010 massiv demonstriert was float & double für Probleme haben (Je nach Typgenauigkeit der Plattform ist dies anzupassen).
Und ja, dies war schon praxisrelevant und hat Geldbeträge in einer Anwendung verfälscht (Wo es um die Aufteilung von Summen über Kostenstellen ging, damals soviel ich noch in Erinnerung habe mit double).
#include <iostream> #include <iomanip> int main() { float f = 10000000; float f2 = 20000000; for(int i=0; i<10000000; ++i) f += 1; std::cout << std::fixed << f << std::endl << f2; }
Wenn ich Genauigkeit brauche wähle ich sicherlich weder float noch double. Für Geldsummen, je nach Rechenregeln (z.B. erinnere ich mich entfernt noch an ein Dokument für Währungsumrechnungen, Fixkomma mit 2 Nachkommastellen für Endsummen und 4 für Berechnungen)...
-
Du könntest im Prinzip auch mit ReadProcessMemory den Wert auslesen. Musst dann halt nur die Mantisse, den Exponent und die Basis einzeln auslesen.
-
asc schrieb:
Wenn ich Genauigkeit brauche wähle ich sicherlich weder float noch double. Für Geldsummen, je nach Rechenregeln (z.B. erinnere ich mich entfernt noch an ein Dokument für Währungsumrechnungen, Fixkomma mit 2 Nachkommastellen für Endsummen und 4 für Berechnungen)...
Wenn ich Genauigkeit auch in den Nachkommastellen brauche wähle ich float oder double, sonst habe ich oft Murks. Es geht aber um Geldbeträge - den zehntel Cent gibt es nur an der Zapfsäule der Tanke, nicht an der Kasse!
Der Fragesteller hat in seinem alten Programm für Geldbeträge bereits double gewählt. Eine Umstellung auf long int wird sicher aufwendig und ist daher nicht zu empfehlen.
Man kann für Geldbeträge durchaus double einsetzen. Z.B. mit dem was du da mal gelesen hast und auch mir schwach in Erinnerung ist. Für die Zielsetzung besser erscheint mir der Einsatz der von mir vorgeschlagenen Funktionen runden() und dtoa(). Ich bin damit stets recht gut zurecht gekommen und vermeide so die Unstimmigkeiten mit double, wo das relevant ist.
Egal, ob long int oder double: Bei Berechungen mit Geldbeträgen muss man genau wissen, was man tut!
-
Was mach ich nun mit mein Programm, dass 33 Cent verschluckt?
int main() { double values = 12.04 + 11.99 + 123.10 + 9000.01 + 900000.19; cout << values << endl; cin.get(); }
-
berniebutt schrieb:
Wenn ich Genauigkeit auch in den Nachkommastellen brauche wähle ich float oder double, sonst habe ich oft Murks. Es geht aber um Geldbeträge - den zehntel Cent gibt es nur an der Zapfsäule der Tanke, nicht an der Kasse!
Nein. Deine Vorstellungen vom Einsatzgebiet von Fließkommazahlen sind falsch. Es geht bei double vs. int nicht um Komma oder kein Komma. Es geht um diskret vs. kontinuierlich*.
Rechnen mit Geld ist ganz klar ein diskretes Problem. Der Einsatz von Fließkommazahlen in der wissenschaftlichen Rechnung hat damit zu tun, dass die dort vorliegenden Probleme häufig Kontinuumsmechanik sind. Das hat überhaupt nichts mit Genauigkeit zu tun!
*: Natürlich sind Fließkommazahlen keine perfekte Repräsentation des Kontinuums - dies ist auf einem Digitalrechner unmöglich. Aber es ist eine gute Näherung.
-
SeppJ schrieb:
Nein. Deine Vorstellungen vom Einsatzgebiet von Fließkommazahlen sind falsch. Es geht bei double vs. int nicht um Komma oder kein Komma. Es geht um diskret vs. kontinuierlich*.
In der Sprache der Mathematiker: natürliche Zahlen (0,1,2,3, ...) und reelle Zahlen. Den Unterschied lernt man doch schon in der Schule oder heute nicht mehr? Die reellen Zahlen heissen in der Schule manchmal Bruchzahlen, wenn ich mich recht erinnere.
Wie könnte jemand als Programmierer mit seiner Arbeit Geld verdienen, wenn er nicht über die grundlegenden Datentypen, deren Einsatz, und der wie bei Geldbeträgen vorhandenen Problematik nicht bescheid wüsste?
Mach mal eine technische oder wissenschaftlich Berechnung mit int statt float. Da fliegst du schnell allein mit dem darstellbaren Wertebereich auf die Schnauze! Ach so, was machst du bei Zins- oder Mehrwertsteuer-Berechnungen mit den Anteilen hinter dem Cent? Wegschmeissen oder geschickt in die eigene Tasche stecken?
-
Sorry berniebutt, aber du liegst in einigen Dingen falsch.
Die Bruchzahlen heißen auch rationale Zahlen und sind nur ein Teil der reellen Zahlen (PI und E und unendlich weitere Zahlen lassen sich nicht als Bruch darstellen). (Soviel zur Schulbildung -)
Und wenn man Zins oder Mehrwertberechnung mit höherer Genauigkeit benutzen will, dann sollte man dafür dann eben eine entsprechende Fixkommazahl mit größerem Nachkommaanteil wählen (aber Fließkommazahlen sind vom Namen her schon ungeeignet, da die Genauigkeit abhängig von der Größe der Zahl ist, d.h. "1Mio. und 15 Cent" lassen sich mit 7 Dezimalstellen Genauigkeit (bei einem 4 Byte float) einfach nicht mehr darstellen).
Für wirklich exakte Berechnungen im wiss. und techn. Bereich (d.h. große Zahlen sowie hohe Genauigkeit im Nachkommaanteil) benötigt man dann entsprechend eigene Datentypen (mittels Fixkommazahlen auf der Basis von 'int').
P.S. Noch ein Beispiel was gegen Fließkommazahlen spricht ist folgendes:
float x = 0; while(++x) cout << x << endl;
Wunder dich dann nicht, daß du keine Zahlen größer als ca. 16 Mio angezeigt bekommst...
Oder teste es einfach mal so aus:
float x = 0; while(x != x+1) { ++x; } cout << x << endl;
Wetten, daß das keine Endlosschleife ist?
(mit 'double' dauert es halt etwas länger...)
-
Wie könnte jemand als Programmierer mit seiner Arbeit Geld verdienen, wenn er nicht über die grundlegenden Datentypen, deren Einsatz, und der wie bei Geldbeträgen vorhandenen Problematik nicht bescheid wüsste?
Das Frage ich mich bei dir auch. Wie man die Problematik bei Geldbeträgen löst, wurde hier schon mehrmals gesagt - und nein: double und float einzusetzen ist nicht die Lösung.
Mach mal eine technische oder wissenschaftlich Berechnung mit int statt float.
Liest du eigentlich die Posts der anderen? Es geht nicht um technische/wissenschaftliche Berechnung, sondern um finanzielle Berechnungen. Und gerade bei solchen Berechnungen darf die inhärente Ungenauigkeit von float und double nicht in einfach in Kauf genommen werden.
-
Th69 schrieb:
float x = 0; while(x != x+1) { } cout << x << endl;
Wetten, daß das keine Endlosschleife ist?
Die Wette gehe ich gerne ein: Erstens erhöhst du x nicht und zweitens vergleichst du ohne eps.
Aber prinzipiell hast du Recht:
#include <iostream> #include <iomanip> using namespace std; int main() { float x = 16777216; cout << sizeof(x) << "; " << setprecision(20) << x << "; " << x + 1; } Ausgabe bei mir: 4; 16777216; 16777216
Was für ein Zufall, dass das 2^24 ist
-
berniebutt schrieb:
Ach so, was machst du bei Zins- oder Mehrwertsteuer-Berechnungen mit den Anteilen hinter dem Cent? Wegschmeissen oder geschickt in die eigene Tasche stecken?
Einige Sprachen und Bibliotheken bieten nicht ohne Grund Währungstypen (Fixkommazahlen) an. float und double ist in allen ernsthaften Anwendungen in denen es um Geld geht, und in denen viele Berechnungen statt finden ungeeignet.
Ganz davon abgesehen das im Bankenwesen durchaus nicht nur mit Centbeträgen gerechnet wird, sondern dafür exakte Vorschriften gibt mit welchen Genauigkeiten etc. zu arbeiten ist, wie bei Berechnungen zu runden ist, wie Umrechnungsungenauigkeiten gebucht werden... Und auch Datenbanken arbeiten in der Regel nicht bei Währungen mit Fließkommazahlen - und das aus sehr guten Gründen.
-
berniebutt schrieb:
In der Sprache der Mathematiker: natürliche Zahlen (0,1,2,3, ...) und reelle Zahlen. Den Unterschied lernt man doch schon in der Schule oder heute nicht mehr? Die reellen Zahlen heissen in der Schule manchmal Bruchzahlen, wenn ich mich recht erinnere.
Wie könnte jemand als Programmierer mit seiner Arbeit Geld verdienen, wenn er nicht über die grundlegenden Datentypen, deren Einsatz, und der wie bei Geldbeträgen vorhandenen Problematik nicht bescheid wüsste?
Mach mal eine technische oder wissenschaftlich Berechnung mit int statt float. Da fliegst du schnell allein mit dem darstellbaren Wertebereich auf die Schnauze! Ach so, was machst du bei Zins- oder Mehrwertsteuer-Berechnungen mit den Anteilen hinter dem Cent? Wegschmeissen oder geschickt in die eigene Tasche stecken?
Tut mir leid, du willst hier mit vermeintlichen Wissen glänzen, machst dich aber nur lächerlich. Wenn dir die Begrifflichkeit Kontinuum vs Diskret nichts sagt, dann ist dies eine Bildungslücke deinerseits. Und was du über wissenschaftliche Rechnungen verzapfst ist ebenfalls kompletter Blödsinn. Zufällig verdiene ich mein Geld damit und kenne mich ein wenig mit dem Thema aus. Viele Kollegen rechnen mit Ganzzahlen und dies ist vollkommen in Ordnung, wenn das Modell entsprechend aussieht. Wie schon gesagt, geht es bei double vs. int nicht um Genauigkeit sondern um die richtige Modellierung des Problems.
-
Danke für die freundlichen Belehrungen! Ich kenne mich da schon aus, sonst hätte ich nicht viele Jahre erfolgreich mit eigenen Mitarbeitern mein Geld sowohl für technisch-wissenschaftliche wie kaufmännische Anwendungen verdienen können. Soll ich den Kunden das Geld etwa zurückgeben - sie waren doch voll zufrieden?
Nun war es aber einmal so, dass es sinnvoll nur FORTRAN und einige andere Compilersprachen gegeben hatte. Da gab es dann für Zahlenwerte nur int (INTEGER) und float (REAL), C und C++ kamen später hinzu. Also hatten wir einen ganzen Sack eigener Funktionen in der Werkzeugkiste, was heutige Compiler an dieser Stelle zusätzlich anbieten. Ist auch gut so, denn jeder Fortschritt ist willkommen!
Nun löst das aber alles nicht das hier nachgefragte Problem. Der Fragesteller hat eben durch Vorarbeiten vor 20 Jahren double für Geldwerte und will damit weiter leben! Soll er alles aufwendig umschreiben oder völlig neu machen?
daddeldu! :p
-
Ändert nichts daran, dass du folgendes geschrieben hast:
Fliesskommazahlen (float, double, ...) sind nun einmal viel genauer als Ganzzahlen (int, ...)
Dass diese Aussage nicht zutrifft, wurde dir auf den letzten Seiten dargelegt, allerdings ohne jegliche Einsicht deinerseits.
daddeldu! :p (Wie dämlich ist das denn?)
-
Nun war es aber einmal so, dass es sinnvoll nur FORTRAN und einige andere Compilersprachen gegeben hatte. Da gab es dann für Zahlenwerte nur int (INTEGER) und float (REAL), C und C++ kamen später hinzu. Also hatten wir einen ganzen Sack eigener Funktionen in der Werkzeugkiste, was heutige Compiler an dieser Stelle zusätzlich anbieten. Ist auch gut so, denn jeder Fortschritt ist willkommen!
Welche Funktionen? Compiler? Dass man für Finanzen keine Fließkommazahlen nehmen soll, gilt sowohl in Fortran als auch in C und C++.
Der Fragesteller hat eben durch Vorarbeiten vor 20 Jahren double für Geldwerte und will damit weiter leben!
Für mich hört sich das etwas anders an:
Belli schrieb:
Deshalb will ich jeden einzelnen Betrag erst Mal in einen Integer - Wert konvertieren
-
Michael E. schrieb:
Welche Funktionen? Compiler? Dass man für Finanzen keine Fließkommazahlen nehmen soll, gilt sowohl in Fortran als auch in C und C++.
- Funktionen: Eigene Funktionen oder Firmware
- Compiler: So gut wie alle Compiler
- Einsatz von Fliesskomma für Finanzen: zunächst nein, bei Beherrschung der Materie jedoch jaGewöhnlich - so auch ich - setzt man für Finanzprojekte keine Fliesskommazahlen ein!
-
Welche Funktionen?
-
Einsatz von Fliesskomma für Finanzen: zunächst nein, bei Beherrschung der Materie jedoch ja
Was soll denn jetzt dieser letzte Teilsatz bedeuten? Wenn man um die Nachteile der Fließkommazahlen weiß, dann wird man sie doch wohl nicht einsetzen - vor allem wenn es heutzutage bessere Alternativen gibt.
-
berniebutt schrieb:
Nun war es aber einmal so, dass es sinnvoll nur FORTRAN und einige andere Compilersprachen gegeben hatte. Da gab es dann für Zahlenwerte nur int (INTEGER) und float (REAL)
In die Zeit von FORTRAN gehört wohl auch die Sprache COBOL. Und dort gibt es sehr wohl einen für den Umgang mit Geld/Währungen passenden Datentyp.