mehrdeutiger Aufruf einer überladener Funktion



  • "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?


  • Mod

    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.


  • Mod

    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 lieber

    for (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..


  • Mod

    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, n ist bei dir const )
    Und meine Version sagt für 121, Keine Primzahl! 😉


  • Mod

    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, n ist bei dir const )

    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, n ist bei dir const )

    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



  • int main(int n)
    

    Das geht nicht. Wenn du wissen willst, was main für Parameter haben kann, googel das mal.

    Ansonsten wird er dir noch sagen, dass sqrt nicht deklariert ist, das ist es nämlich in der Headerdatei cmath.

    Außerdem hast du das ganz schön umständlich gelöst.

    Deine Schleife kannst du auch gleich ganz leicht in eine hübsche Funktion packen.
    Könnte so aussehn.

    #include <iostream>
    #include <cmath>
    using namespace std;
    
    bool ist_primzahl(int zahl)
    {
        if(zahl < 2)
            return false;
        if(zahl == 2)
            return true;
        for(int i = 2; i <= (zahl / 2); ++i)
            if(zahl % i == 0)
                return false;
        return true;
    }
    
    int main()
    {
        int n;
        cout << "Geben Sie eine Zahl ein:\n";
        cin >> n;
        if(ist_primzahl(n))
            std::cout << "Primzahl!\n";
        else
            std::cout << "Keine Primzahl!\n";
        return 0;
    }
    


  • Wenn ich das Programm so kopiere sagt es mir 121 ist prim

    Irgendwas stimmt doch hier mit meinem Programm nicht.
    Und anstatt bis n/2 reicht es ja bis sqrt(n)+1 zu gehen.

    Wieso klappt das bei mir nicht?



  • Du musst schon den Quellcode zeigen, der nicht funktioniert...



  • So siehts jetzt aus:
    Ich habe den Verdacht, dass lediglich auf modulo 2 und 3 getestet wird. Zahlen wie 25,121 sind prim, Zahlen die gerade oder durch 3 teilbar sind werden als nicht prim ausgegeben.

    #include <iostream>
    #include <cmath>
    using namespace std;
    
    bool ist_primzahl(int zahl)
    {
        if(zahl < 2)
    	{
    		return false
    	}
    	if (zahl==3)
    	{
    		return true
    	}
    	if(zahl % 2 ==0)
    	{
    		return false
    	}
    	for(unsigned int i=3,i<=(sqrt(zahl)+1),i+=2)
    	{
    		if(zahl % i ==0)
    		{
    			return false
    		}
    	}
    	return true;
    }
    
    int main()
    {
        int n;
        cout << "Geben Sie eine Zahl ein:\n";
        cin >> n;
        if(ist_primzahl(n))
            cout << "Primzahl!\n";
        else
            cout << "Keine Primzahl!\n";
        return 0;
    }
    

  • Mod

    ray91 schrieb:

    So siehts jetzt aus:

    Da schon mehr als einmal auf C&P hingewiesen wurde, gehe ich mal davon aus, dass das ein Trollversuch sein soll.


Anmelden zum Antworten