Benutzer mit den meisten Antworten
floor( 11 ) = 10

Frage
-
Schönen guten Tag alle zusammen :D
Ich hab mal ne kleinen Frage und wäre um Hilfe seehr dankbar :D
ich bin gerade dabei ein kleines Programm zu schreiben, dass mit seehr großen Zahlen umgehen muss. deshlab verwende ich dafür die Boost-Library, ich hoffe die sagt euch was ;D Um nun ganz große floats zu machen, habe ich also nen typ definiert namens float1024. C++ zeigt mir keine Fehler dabei an, wenn ich die Zahl in die floor-Funktion einsetze. Bei den meisten Zahlen funktioniert das auch auch wunderbar :D
Also hier geb ich etz mal ein Code-Beispiel und die ausgaben, die mein PC dabei immer versursacht.. :D
#include <math.h> #include <boost\multiprecision\cpp_dec_float.hpp> typedef number<cpp_dec_float<1024> > float1024; int main() { float1024 n; for (;;) { cout << "Geben Sie eine Zahl ein: "; cin >> n; cout << "floor (n) = " << floor(n) << endl; } return 0; }
So, man erwartet ja nun, wenn man für n verschiedene Zahlen einsetzt, dass dann auch IMMER richtig abgerundet wird. Fehlanzeige. setzt man beispielsweise 1.25 ein, kommt 1 raus setzt man 9 ein kommt 9 raus, jedoch, und das ist das magische.. setzt man 11 ein, kommt 10 raus. Aber warum rundet er hier an dieser setlle nicht num nächstgelegenem integer ab, sondern.. macht es einfach um eins kleiner, wo es doch aj bei 9 bspw. funkioniert. Ich selbst bin diesbezüglich ratlos, deshalb frage ich euch :D
Habt ihr eine Idee zur Lösung des Problems, oder einen Möglichkeit es zu umgehen? wenn ja, ich wäre euch extremst dankbar :D
freundlich mit einem Lächeln grüßend
aCrazyJo :D
Antworten
-
Je nachdem, was das Ziel deines Projekts ist, wäre es möglicherweise sinnvoll nach Libraries zu suchen, die BigInts anbieten (oder wie immer die sich dann nennen). Bei Floats hast du immer das Problem mit Ungenauigkeit, das irgendwie umschifft werden muss. ".NET" hat ja bereits ziemlich große Integer implementiert und es gibt sicher irgendwo auch fertige Libs für noch größere.
Und letztlich kann man fast alle Floats ja auch durch mehr oder weniger große Brüche darstellen, die manchmal sogar genauer sind, als es die Float je sein könnte. Diese dann darzustellen in einem String wäre dann eine andere Baustelle. Aber je nach Anwendungsfall ist es vielleicht günstiger mit Ganzzahlen zu rechnen. Okay, bei PI, e und Konsorten müsste man dann auf irgendwelche einigermaßen genauen Bruchdarstellungen/abgebrochene Kettenbruchentwicklungen ausweichen, aber das ist ja vielleicht gar nicht von Interesse in deinem Projekt.
LG, Dennis.
EDI Consultant/Developer
Ich nutze meistens VB6 und VS2005 bis VS2012
Bitte die Antworten sowie weitere hilfreiche Beiträge von Mitgliedern markieren. Vielen Dank.
- Als Antwort vorgeschlagen Martin RichterModerator Mittwoch, 28. August 2013 09:54
- Als Antwort markiert aCrazyJo Mittwoch, 28. August 2013 11:34
Alle Antworten
-
Hi,
Gute nachricht zuerst: Boost ist eine bekannte und zum Teil auch schon in den Spec. von C++ übernommene Lib. Also sollte diese Bekannt sein.
Ohne es jetzt im einzelnen getestet zu haben, kann dein Problem daher stammen das die Gleitkommazahl zu Ungenau gespeichert ist. Also 11 als Float kann als 10.999999999999 (wie es dazu kommt siehe ). Daher schneidet dann floor die 0.99999999 einfach ab und siehe es bleibt 10 übrig.
Einfach mal versuchen mit double probieren.
-
schönen Guten Abend :D
Danke als erstes für desen doch sehr interessanten Bericht. Ist gut zu wissen ;D
Die Idee mit double ist prinzipiell nicht schlecht. Jedoch ist das Problem an double, dass es auf 32bits beschreänkt ist, und das der grund war, wieso ich auf die boost-library zurückgreifen musste, um eben größere Zahlen in meine berechnungen mit einzubeziehen. Ich möchte nämlich geren mit Zahlen im Bereich von 10^256 und mehr arbeiten.
Gibt es da vlt noch andere Möglichkeiten um das Problem zu lösen? ;D
Hier mal den Ausschnitt vom original Code, wollte das mit obigem Beispiel nur vereinfachen. Vlt kann es ja zur Findung einer Lösung beitragen :D
bool prime_numbers::is_prime (float1024 n) { float1024 c = 1; for (bool prime = false; prime == false;) { c = c + 1; float1024 r = n - (floor(n/c) * c); //no divisor found -> prime_number if (n == c) { prime = true; return true; } //integer divisor if (r == 0) { prime = false; return false; } } return false; }
es gelten die selben header-files und Datentypen wie oben. Die Funktion selbst wird im Hauptprogramm so lange aufgerufen, bis true zurückgegeben wird.
Schonmal dankend und immer noch mit einem Lächeln auf dem Gesichht :D
aCrazyJo -
Je nachdem, was das Ziel deines Projekts ist, wäre es möglicherweise sinnvoll nach Libraries zu suchen, die BigInts anbieten (oder wie immer die sich dann nennen). Bei Floats hast du immer das Problem mit Ungenauigkeit, das irgendwie umschifft werden muss. ".NET" hat ja bereits ziemlich große Integer implementiert und es gibt sicher irgendwo auch fertige Libs für noch größere.
Und letztlich kann man fast alle Floats ja auch durch mehr oder weniger große Brüche darstellen, die manchmal sogar genauer sind, als es die Float je sein könnte. Diese dann darzustellen in einem String wäre dann eine andere Baustelle. Aber je nach Anwendungsfall ist es vielleicht günstiger mit Ganzzahlen zu rechnen. Okay, bei PI, e und Konsorten müsste man dann auf irgendwelche einigermaßen genauen Bruchdarstellungen/abgebrochene Kettenbruchentwicklungen ausweichen, aber das ist ja vielleicht gar nicht von Interesse in deinem Projekt.
LG, Dennis.
EDI Consultant/Developer
Ich nutze meistens VB6 und VS2005 bis VS2012
Bitte die Antworten sowie weitere hilfreiche Beiträge von Mitgliedern markieren. Vielen Dank.
- Als Antwort vorgeschlagen Martin RichterModerator Mittwoch, 28. August 2013 09:54
- Als Antwort markiert aCrazyJo Mittwoch, 28. August 2013 11:34
-
Vielen Dank, irgendwie.. ich weiss auch nicht, aber bis jettz hab ich mich offensichtlich doof angestellt :D aber danke für den Hinweis, ich solle es wieder mit großen Integer versuchen. Klappt nun wunderbar!
Ich danke euch beiden herzlichst :D
am freudigen Weiterprogrammieren
aCrazyJo
-
Ach, nicht ärgern. Das ist nur der ganz normale Programmierer-Tunnelblick, den man irgendwann bekommt, wenn man zu lange auf den eigenen Code starrt. ;-)
Wünsche schönes Weiterprogrammieren!
LG, Dennis.
EDI Consultant/Developer
Ich nutze meistens VB6 und VS2005 bis VS2012
Bitte die Antworten sowie weitere hilfreiche Beiträge von Mitgliedern markieren. Vielen Dank.