mehrdeutiger Aufruf einer überladener Funktion
-
Meinst du welchen Logarithmus ich verwenden möchte? Oder wie soll ich das verstehen.
Das gleiche Problem habe ich an einer anderen Stelle mit der CodeZeile
const unsigned int iMax = sqrt(n) + 1;Gibt haargenau den gleichen Fehler nur mit sqrt anstatt mit log.
Aber mit sqrt kann er doch nichts falsch verstehen.
Anscheinend hängt es ja mit dem Typ zusammen, ob double,float etc...
Aber ich denke ich habe deine Frage nicht gut genug verstanden.
Solange bin ich noch nicht bei c++ dabei.
-
Mit der Frage war gemeint: Es gibt drei Funktionen namens
log. Eine nimmt einen float entgegen und gibt float zurück, eine macht das gleiche für double und eine für long double. Ein int ist weder ein float noch ein double noch ein long double. Aber ein int kann implizit in jeden dieser drei Typen umgewandelt werden. Wenn du der log-Funktion nun einen int gibst, dann ist unklar, welche der srei Funktionen gemeint ist und du musst daher eine explizite Umwandlung (static_cast) vornehmen, um die Mehrdeutigkeit aufzulösen.In C++11 gibt es übrigens noch eine Überladung für integrale Datentypen, da wäre der Fall für int eindeutig. Guck doch mal, ob dein Compiler C++11 kann.
-
#include <complex> ... std::sqrt<float>(r); std::log<float>(r); ...
-
Sone schrieb:
#include <complex> ... std::sqrt<float>(r); std::log<float>(r); ...Ich hoffe, das soll Klugscheißerei sein, dass es mehr als die drei von mir genannten Überladungen gibt, nicht als ernsthafte Alternative. Bei dir weiß man ja nie. Da du keinen Kommentar dazu abgibst, lege ich es mal zu deinem Vorteil als Klugscheißerei aus.
-
So, schonmal danke für die Hilfe, jetzt weiß ich wenigstens warum das Programm nicht funktioniert. Ich glaube aber, dass ich es noch nicht richtig verstehe mit static_cast umzugehen. Ich poste mal die kleine Teilfunktion des Programs hier vollständig:
static bool IsPrime(unsigned int n) { //unsigned long m; if (n < 2) return false; if (n < 4) return true; if (n % 2 == 0) return false; //m=static_cast<unsigned long>(n); const unsigned int iMax = sqrt(n/*m*/) + 1; unsigned int i; for (i = 3; i <= iMax; i += 2) if (n/*m*/ % i == 0) return false; return true; }Die Kommentar wären meine Änderung gewesen, leider ohne Erfolg

Long ist natürlich noch viel zu klein, aber darum geht es ja erstmal nicht.
-
"Ohne Erfolg" ist keine gute Fehlerbeschreibung. Davon abgesehen castest du nach long double. Wieso denn? SeppJ hat doch schon gesagt was für Typen gehen:
Eine nimmt einen float entgegen und gibt float zurück, eine macht das gleiche für double und eine für long double. Ein int ist weder ein float noch ein double noch ein long double.
Auch ein unsigned long ist keines der 3 Typen.
So sollte es (z.B.) funktionieren:
static bool IsPrime(unsigned int n) { if (n < 2) return false; if (n < 4) return true; if (n % 2 == 0) return false; const unsigned int iMax = sqrt(static_cast<double>(n)) + 1; unsigned int i; for (i = 3; i <= iMax; i += 2) if (n % i == 0) return false; return true; }
-
Kleiner Fehler: Das erste oben soll natürlich
Davon abgesehen castest du nach unsigned long.
heißen.
-
So, wie du es geschrieben hast sagt er:
'Initialisierung': Konvertierung von 'double' in 'const unsigned int', möglicher Datenverlust
Ansonsten kein Fehler mehr. Ich möchte ja große Primzahlen einsetzen(ca 1000 Binärstellen)
-
SeppJ schrieb:
Sone schrieb:
#include <complex> ... std::sqrt<float>(r); std::log<float>(r); ...Ich hoffe, das soll Klugscheißerei sein, dass es mehr als die drei von mir genannten Überladungen gibt, nicht als ernsthafte Alternative. Bei dir weiß man ja nie. Da du keinen Kommentar dazu abgibst, lege ich es mal zu deinem Vorteil als Klugscheißerei aus.
Es sollte in der Tat Klugscheißerei sein. Aber erklär mir noch schnell, wieso das keine Alternative ist, weil hier implizit in ein
complex<>und zurück gecastet wird? Oder weil der Algorithmus langsamer/anders ist?
-
Sone schrieb:
weil hier implizit in ein
complex<>und zurück gecastet wird?Cast ist lustig. Das ist ein fetter Kontruktor und Konvertierungsoperator.
Oder weil der Algorithmus langsamer/anders ist?
Aber Hallo. Gib mal an, wie du den Logarithmus einer komplexen Zahl berechnest und den einer reellen Zahl und staune, wie unterschiedlich der Aufwand ist.
-
ray91 schrieb:
So, wie du es geschrieben hast sagt er:
'Initialisierung': Konvertierung von 'double' in 'const unsigned int', möglicher Datenverlust
Ansonsten kein Fehler mehr. Ich möchte ja große Primzahlen einsetzen(ca 1000 Binärstellen)
Das liegt daran das
sqrt(static_cast<double>(n)) + 1;als double variante einen double zurückgibt. Diesen weißt du dann einem int zu (iMax). Eventuell vorhandene Nachkommastellen werden also einfach abgeschnitten. Das ist dann der Datenverlust. Wenn du 1000 Binärstellen haben willst, reichen aber allgemein solche Datentypen eh nicht, da müsstest du dich wohl schon nach einer extra Bibliothek umschaun, die dann wahrscheinlich auch eine völlig andere sqrt-Funktion anbieten.
-
KMT schrieb:
Das liegt daran das
sqrt(static_cast<double>(n)) + 1;als double variante einen double zurückgibt. Diesen weißt du dann einem int zu (iMax). Eventuell vorhandene Nachkommastellen werden also einfach abgeschnitten. Das ist dann der Datenverlust.
Das ist eigentlich das erwartete Verhalten. Der wirkliche Datenverlust entsteht bei Werten die größer als INT_MAX sind (bzw. kleiner als INT_MIN).
-
Hallo, ich habe noch eine kleine Frage. Anscheinend bin ich doof, denn ich finde den Fehler nicht.
Folgender Quelltext:const unsigned int iMax = sqrt(n) + 1; unsigned int i; bool m=true; for (i = 3; i <= iMax; i += 2) { if (n % i == 0) { m=false; } } if (m==true) { cout << "Primzahl"; } else { cout << "Keine Primzahl"; }Für Zahlen wie 9 und 15 klappts.
Aber ab 25 sagt er mir, es sei eine Primzahl. Woran liegt das? Das gleiche gilt für 49,121 etc. Irgendwas muss an meiner for-Schleife falsch sein.
Ich denke es ist kein großes Problem, leider finde ich es nicht.Danke für die Hilfe!
-
Bitte C++-Tags nutzen.
Ja, deine Schleife ist Blödsinn.
Nimm lieberfor (unsigned int i = 2; i < n / 2;++i) if (n % i == 0) { std::cout << "Keine "; break; } std::cout << "Primzahl!";
-
Ich würde das gerne mit dem iMax machen
Das erspart viel Rechenarbeit bei großen Primzahlen.const unsigned int iMax = sqrt(n) + 1; for (unsigned int i = 3; i <= iMax / i+=2) if (n % i == 0) { cout << "Keine Primzahl "; break; }cout << "Primzahl";
Hier sagt er mir trotzdem für Zahlen wie 121, dass es eine Primzahl sei..
-
Zeig bitte deinen richtigen Code. Dein Codebeispiel kann unmöglich compilieren. Bitte nur Copy & Paste benutzen. Siehe dazu den dritten Link in meiner Signatur. Sonst verschwendest du nur unsere und deine Zeit mit Fehlern, die gar keine sind, sondern beim Abschreiben entstanden sind.
-
ray91 schrieb:
Ich würde das gerne mit dem iMax machen
Das erspart viel Rechenarbeit bei großen Primzahlen.Nein, tut es nicht. Compiler optimieren, weißt du. (Ich hoffe,
nist bei dirconst)
Und meine Version sagt für 121, Keine Primzahl!
-
Sone schrieb:
ray91 schrieb:
Ich würde das gerne mit dem iMax machen
Das erspart viel Rechenarbeit bei großen Primzahlen.Nein, tut es nicht. Compiler optimieren, weißt du. (Ich hoffe,
nist bei dirconst)Wieder Unsinn. Kein Compiler der Welt optimiert dir eine Schleife bis n/2 zu sqrt(n), weil er erkennt, dass die Bedingung nie wieder wahr wird. Mit diesem Argument könnte der Compiler anstatt die Schleife zu erzeugen auch erkennen, dass hier Primzahlen gesucht werden und stattdessen einen effizienten Algorithmus generieren. Hör gefälligst auf, zu jedem Thread Müll zu labern! Ich war die letzten 15 Minuten beschäftigt nur deinen Schrott zu korrigieren!
-
SeppJ schrieb:
Sone schrieb:
ray91 schrieb:
Ich würde das gerne mit dem iMax machen
Das erspart viel Rechenarbeit bei großen Primzahlen.Nein, tut es nicht. Compiler optimieren, weißt du. (Ich hoffe,
nist bei dirconst)Wieder Unsinn. Kein Compiler der Welt optimiert dir eine Schleife bis n/2 zu sqrt(n), weil er erkennt, dass die Bedingung nie wieder wahr wird.
Bist du doof oder so?
Ich meinte, dass man nicht den Endindex in eine Variable auslagern muss!! Lies doch!
-
Also ich hoffe mal es ist okay, dass ich jetzt den ganzen Code poste:
#include "stdafx.h" #include <iostream> using namespace std; int main(int n) { cout << "Geben Sie eine Zahl ein:\n"; cin >> n; if (n<2) { cout << "Keine Primzahl\n"; system("pause"); return 0; } if (n==3) { cout << "Primzahl\n"; system("pause"); return 0; } if (n % 2 == 0) { cout << "Keine Primzahl\n"; system("pause"); return 0; } const unsigned int iMax = sqrt(n) + 1; for (unsigned int i = 3; i <= iMax, i+=2) if (n % i == 0) { cout << "Keine "; break; } cout << "Primzahl!"; system("pause"); return 0; }Da kommt eine Fehlermeldung, diese verschwindet aber sofort, sodass ich sie gar nicht erkennen kann. Wie gesagt, ich bin der Meinung, dass sich irgendwo ein kleiner blöder Programmierfehler eingeschlichen hat. Bin noch nicht lange dabei.
Schonmal vielen Dank