ist ein fehler in diesem programm?



  • joomoo: Danke, ich weiß, was VC bezüglich for-Schleifen durchgehen lässt und was nicht, ich hab schließlich lange mit ihm gearbeitet. Du solltest mir allerdings eher die Stelle im Programm zeigen, wo der Bug ausgenutzt wird.

    joomoo schrieb:

    Außerdem besitzt er eine Template-Unterstütztung die du in die Tonne treten kannst. Deswegen ist er veraltet. PUNKT!

    Meine Meinung, hab nie was anderes behauptet. Deshalb frage ich mich, warum du so auf der Veraltung rumhackst.

    return hat immer noch seine Darseinsberechtigung in der main-Funktion (mehrere Exit Points, andere Rückgabewerte). Wieso also nicht immer schreiben? Wieso als alten Müll bezeichnen?

    mehre Exit Points gab es in diesem Beispiel nicht!

    Hab ich auch nicht geschrieben. Ich frage lediglich, warum man nicht konsequent sein sollte.



  • Natürlich kann man nicht immer stur nach dem Standard programmieren. Man muss dann halt für die einzelnen Compiler workarounds bauen alá:

    #ifdef __MSVC7
    ...
    #endif
    


  • Firebyte::Username schrieb:

    @Michael E.

    Kannst du mal das Primzahlprogramm posten, wie es nach deiner Syntax aussähe?

    #include <iostream>
    using namespace std;
    
    int main()
    {
    	for(int i = 2; i < 100; ++i)
    	{
    		bool isPrime = true;
    
    		for(int j = 2; j <= i/2; ++j)
    		{
    			if(i % j == 0)
                    isPrime = false;
    		}
    
    		if(isPrime == true)
                cout << i << " ist eine Primzahl.\n";
    	}
    
    	return 0;
    }
    

    Wieso willst du das wissen?



  • Firebyte::Username schrieb:

    Natürlich kann man nicht immer stur nach dem Standard programmieren. Man muss dann halt für die einzelnen Compiler workarounds bauen alá:

    #ifdef __MSVC7
    ...
    #endif
    

    Also programmierst du für Compiler...



  • Michael E. schrieb:

    Firebyte::Username schrieb:

    @Michael E.

    Kannst du mal das Primzahlprogramm posten, wie es nach deiner Syntax aussähe?

    #include <iostream>
    using namespace std;
    
    int main()
    {
    	for(int i = 2; i < 100; ++i)
    	{
    		bool isPrime = true;
    		
    		for(int j = 2; j <= i/2; ++j)
    		{
    			if(i % j == 0)
                    isPrime = false;
    		}
    		
    		if(isPrime == true)
                cout << i << " ist eine Primzahl.\n";
    	}
    	
    	return 0;
    }
    

    Wieso willst du das wissen?

    Da hätte ich auch nichts gegen, aber in dem Buch sind die Variablen am Anfang, außerde sind dort keine Leerzeichen zwischen Operatoren, und du hast ja jetzt selber ne Klammer bei dem Zweiten for benutzt! So säh das im Buchstyle aus:

    #include <iostream>
    using namespace std;
    
    int main()
    {
            int i, j;
            bool isPrime;
    	for(i=2;i<100;++i)
    	{
    		bool isPrime = true;
    		for(j=2; j<=i/2;++j)
    		if(i % j == 0) isPrime = false;
    
    		if(isPrime == true)
                    cout<<i<<" ist eine Primzahl.\n";
    	}	
    	return 0;
    }
    


  • Und?



  • ich bedanke mich für die zahlreichen antworten.
    aber noch ne frage:
    was ist VC6.0?

    und übrigens ich habe schon öfters fehler in diesem buch gefunden!!
    obwohl es auf der seite nicht als fehlerhalt und zugleich als schlecht eingestuft wird
    hier der link:
    http://www.c-plusplus.net/cms/modules.php?op=modload&name=mbBooks&file=index&func=isbn&isbn=3826609808

    ben1990





  • #include <iostream>
    using namespace std;
    
    bool isprime(int n)
    {
      int sqrt_n=static_cast<int>(sqrt(double(n)));
      for (int i=2; i<=sqrt_n; ++i)
        if (!(n%i)) return false;
      return true;
    }
    
    int main()
    {
      static const int bis=10;
    
      for (int i=2; i<bis; ++i)
        if (isprime(i))
          cout << i << endl;
    }
    

    ... oder das ganze als Metaprogramm ...

    #include <iostream>
    
    template <int n, int a, int b, bool eq=a==b>
    struct isprime_helper;
    
    /**
     *  @brief Ermittelt ob Zahl eine Primzahl ist (Brute-Force-Methode)
     *  @param n Der zu testende Wert
    */
    template <int n>
    struct isprime
    {
      /**
       *  Zahle bis max=sqrt(n) testen. Für sqrt(n)<2 gilt max=2
       */
      static const int sqrt_n = static_cast<int>(sqrt(n));
      static const int max = sqrt_n<2 ? 2 : sqrt_n;
    
      static const bool value=isprime_helper<n, 2, 2>::value;
    };
    
    struct isprime<1>
    { static const bool value=false; };
    
    template <int n, int a, int b>
    struct isprime_helper<n, a, b, false>
    { static const bool value=(n%a==0) ? false : isprime_helper<n, a+1, b>::value;};
    
    template <int n, int a, int b>
    struct isprime_helper<n, a, b, true>
    { static const bool value=(n%a==0) ? false : true; };
    
    int main()
    {
      std::cout << isprime<5>::value << std::endl;
      std::cout << isprime<100>::value << std::endl;
    }
    


  • lucky_tux schrieb:

    #include <iostream>
    using namespace std;
    
    bool isprime(int n)
    {
      int sqrt_n=static_cast<int>(sqrt(double(n)));
      for (int i=2; i<=sqrt_n; ++i)
        if (!(n%i)) return false;
      return true;
    }
    
    int main()
    {
      static const int bis=10;
    
      for (int i=2; i<bis; ++i)
        if (isprime(i))
          cout << i << endl;
    }
    

    ... oder das ganze als Metaprogramm ...

    #include <iostream>
    
    template <int n, int a, int b, bool eq=a==b>
    struct isprime_helper;
    
    /**
     *  @brief Ermittelt ob Zahl eine Primzahl ist (Brute-Force-Methode)
     *  @param n Der zu testende Wert
    */
    template <int n>
    struct isprime
    {
      /**
       *  Zahle bis max=sqrt(n) testen. Für sqrt(n)<2 gilt max=2
       */
      static const int sqrt_n = static_cast<int>(sqrt(n));
      static const int max = sqrt_n<2 ? 2 : sqrt_n;
    
      static const bool value=isprime_helper<n, 2, 2>::value;
    };
    
    struct isprime<1>
    { static const bool value=false; };
    
    template <int n, int a, int b>
    struct isprime_helper<n, a, b, false>
    { static const bool value=(n%a==0) ? false : isprime_helper<n, a+1, b>::value;};
    
    template <int n, int a, int b>
    struct isprime_helper<n, a, b, true>
    { static const bool value=(n%a==0) ? false : true; };
    
    int main()
    {
      std::cout << isprime<5>::value << std::endl;
      std::cout << isprime<100>::value << std::endl;
    }
    

    Hast du toll gemacht......aber glaubst du dass das Ben1990 irgendwie weiter bringt?



  • @lucky_tux

    Ich bekomme beim Meta-Programm folgende Meldung:
    main9.cpp:17: error: a function call cannot appear in a constant-expression
    bei der Zeile mit sqrt(). Muss ich was an meinem Compiler einstellen oder woran leigt das?

    mfg.



  • Ich wage zu behaupten dass das Metaprogramm nicht funktioniert, weil das Metaprogramm nicht vollständig instanziiert werden kann. Denn der sqrt-Aufruf kann zur Compilezeit einfach nicht konstant ausgewertet werden.



  • ja! erste geposteten funktion ist ein wenig modifiziert. Es wird nur der Rest aller Zahlen bis \|n (Wurzel n), für n gleich zu testender wert, getestet. Bei einer Vielzahl an Werten kann dadurch so mach eine Sekunde eingespart werden.

    Bei der zweiten Variante weiß ich nicht ob es ihm weiterhilft. Aber vlt. hilft es jemand anderem weiter. Die Zeiteinsparung spricht jedenfalls (meiner Meinung nach) für sich! In dem zweiten Beispiel wird nämlich die komplette Berechnung ob es sich um eine Zufallszahl handelt zu Zeiten des Kompilierens ausgeführt



  • Bei mir funktioniert alles. Die einzige Fehlermeldung die ich bekomme ist folgende 😉

    main.cpp:42:1: Warnung: Kein Newline am Dateiende

    Wie rufst du die Metafunktion auf? Natürlich lässt sich die Metafunktion nur mit einem konstanten ausdruck aufrufen, also nicht mit einer Laufvariablen einer Schleife.



  • lucky_tux schrieb:

    Bei mir funktioniert alles. Die einzige Fehlermeldung die ich bekomme ist folgende 😉

    main.cpp:42:1: Warnung: Kein Newline am Dateiende

    Wie rufst du die Metafunktion auf? Natürlich lässt sich die Metafunktion nur mit einem konstanten ausdruck aufrufen, also nicht mit einer Laufvariablen einer Schleife.

    Wenn ich einfach nur deinen Beispiel-Code compilieren will, tritt das Problem auf. Ich hab gcc 3.4.4.

    mfg.



  • #include <iostream>
    
    template <bool Val, typename True, typename False>
    struct if_ : public True
    {
    };
    
    template <typename True, typename False>
    struct if_<false, True, False> : public False
    {
    };
    
    template <bool Val>
    struct BoolType
    {
        static const bool value = Val;
    };
    
    template <unsigned int N, int i, bool Val>
    struct isprime_helper : public
                             if_<(i*i > N)
                               , BoolType<true>
                               , if_<(N % i)
                                    , isprime_helper<N, i + 1, Val>
                                    , BoolType<false>
                                    >
                               >
    {};
    
    template <unsigned int N>
    struct isprime
    {
        static const bool value = isprime_helper<N, 2, false>::value;
    };
    
    template<>
    struct isprime<1>
    {
        static const bool value = false;
    };
    
    int main()
    {
      std::cout << isprime<5>::value << std::endl;
      std::cout << isprime<100>::value << std::endl;
    }
    

    So funktionierts.

    Spacelord schrieb:

    Hast du toll gemacht......aber glaubst du dass das Ben1990 irgendwie weiter bringt?

    Dann passt es doch sehr gut zum Rest des Threads 🙄



  • lucky_tux schrieb:

    ... oder das ganze als Metaprogramm ...

    Hm... 🙄 ich weiss nicht, ich weiss nicht:

    Statt den Standard zu zitieren zitiere ich zur Abwechslung mal Comeau C++:

    "ComeauTest.c", line 17: error: identifier "sqrt" is undefined
        static const int sqrt_n = static_cast<int>(sqrt(n));
                                                   ^
    
    "ComeauTest.c", line 17: error: function call is not allowed in a constant expression
        static const int sqrt_n = static_cast<int>(sqrt(n));
                                                   ^
    
    "ComeauTest.c", line 23: error: specializing class "isprime<1>" without "template<>"
              syntax is nonstandard
      struct isprime<1>
             ^
    

    Viel mehr muss man dazu nicht sagen. 👎



  • #include <iostream>
    using namespace std;
    
    int main()
    {
        cout << "2 ist eine Primzahl\n";
        cout << "3 ist eine Primzahl\n";
        cout << "5 ist eine Primzahl\n";
        // ...
    }
    

    Die Geschwindigkeit spricht für sich 🙄



  • template <unsigned int N, int i, bool Val> 
     struct isprime_helper : public 
                              if_<(i*i > N) 
                                , BoolType<true> 
                                , if_<(N % i) 
                                     , isprime_helper<N, i + 1, Val> 
                                     , BoolType<false> 
                                     > 
                                > 
     {};
    

    @.filmor:

    Sehr geschickt gelöst das Problem mit sqrt. Wenigstens einer der die Funktionalität der Metaprogrammierung nicht grundlos unterschätzt.

    @Antiposer:

    Ich finde es schade, dass sich so wenige Leute mit der Metaprogrammierung auseinandersetzen. Vorallendingen Anfänger sind von dem neuen, noch recht unerforschten (Bezug auf Libraries wie die MPL) Konzepten der Metaprogrammierung abgeschreckt. Vorallendingen in wissenschaftlichen Applikationen würde ich diese Art der Programmierung nie unterschätzen. Die MPL z.B. etliche Möglichkeiten für mathematische Berechnungen, Type Traits und Manipulation, uvm.



  • lucky_tux schrieb:

    Vorallendingen Anfänger sind von dem neuen, noch recht unerforschten (Bezug auf Libraries wie die MPL) Konzepten der Metaprogrammierung abgeschreckt.

    Ich denk eher, dass die Syntax und die Programmlogik noch zu schwer für nen Anfänger sind.


Anmelden zum Antworten