Warnings in C++



    1. Wieso gibt es überhaupt das Warning? Float ist doch größer als int?

    Und was ist genauer?

    1. Wenn ich dieses #pragma in einen Header schreibe, wird dann das Warning für ALLE Dateien deaktiviert, in die ich den Header einbinde?

    Japp - deshalb:

    #pragma warning(push)
    #pragma warning(disable:4244)
    //weitere warnings deaktivieren
    
    /* quellcode */
    
    #pragma warning(pop)
    
    uint pow(uint b, int e)
    {
    	return uint(std::pow(float(b), e));
    }
    

    aber ich würd so ne fkt wahrscheinlich niemals schreiben^^

    bb



  • uint pow(uint b, int e)
    {
    	return uint(std::pow(float(b), e));
    }
    

    Dein Code liefert nach wie vor das Warning, weil du e nicht nach float castest.

    Ist dann so ein "#pragma warning( disable : 4507 34 )" nur gültig für eine Übersetzungseinheit oder ist das eher ein Flag, das ab dem Zeitpunkt gilt (für ALLE folgenden Übersetzungseinheiten), wenn der Compiler es verarbeitet?

    unskilled schrieb:

    aber ich würd so ne fkt wahrscheinlich niemals schreiben^^

    Aha. Und wieso nicht? Ich brauche nun mal in meinem Code ständig ein e^b, wobei beides unsigned ints sind. Wie sollte ich das denn sonst machen?



  • warnerBros schrieb:

    uint pow(uint b, int e)
    {
    	return uint(std::pow(float(b), e));
    }
    

    Dein Code liefert nach wie vor das Warning, weil du e nicht nach float castest.

    also msvc9 kennt die überladung von pow - das die nicht im standard ist, hab ich gerad eben erst gesehen^^
    dann machste eben noch nen float() um das e^^

    warnerBros schrieb:

    Ist dann so ein "#pragma warning( disable : 4507 34 )" nur gültig für eine Übersetzungseinheit oder ist das eher ein Flag, das ab dem Zeitpunkt gilt (für ALLE folgenden Übersetzungseinheiten), wenn der Compiler es verarbeitet?

    Ist eher so ein Flag - kann man gut mit nem Makro vergleichen...
    Hatte ich aber vorhin schon mal geschrieben...
    btw: disable : 4507 34 ist ja mal extrem hässlich...
    würd ich lieber 2 zeilen für nehmen... (zu mal ich so und so hinter jedes pragma warning die warnung als kommentar schreib)
    falls du noch fragen dazu hast:
    http://msdn.microsoft.com/en-us/library/2c8f766e(VS.80).aspx

    unskilled schrieb:

    aber ich würd so ne fkt wahrscheinlich niemals schreiben^^

    Aha. Und wieso nicht? Ich brauche nun mal in meinem Code ständig ein e^b, wobei beides unsigned ints sind. Wie sollte ich das denn sonst machen?

    um das zu wissen solltes du evtl erst mal sagen, was du machen willst und dann wüsste vll jmd nen besseren weg... auf jeden fall ist der cast von oben nicht all zu ungefährlich... (der vom pow-ergebnis nach uint)
    ich find schon allein uint komisch - was ist das fürn typedef?

    bb

    edit:
    in dem standard draft von 2005 existiert diese überladung auch:
    float pow (float , int );
    allerdings müsste ich jetzt im C standard nachgucken um zu wissen, ob pow ne konstante Laufzeit hat oder linear von n abhängig ist - im zweiten Fall würd ich mir selbst ne pow-fkt schreiben und im ersten würd ich hier posten und fragen, was der rest machen würde^^


  • Mod

    warnerBros schrieb:

    Wie sollte ich das denn sonst machen?

    selber schreiben?

    uint pow(uint b, uint e)
    {
        uint r = 1;
        while ( e != 0 )
        {
            if ( e % 2 != 0 )
                r *= b;
            e /= 2;
            b *= b;
        }
        return r;
    }
    


  • unskilled schrieb:

    um das zu wissen solltes du evtl erst mal sagen, was du machen willst und dann wüsste vll jmd nen besseren weg...

    Habe ich bereits gesagt. b^e, wobei beides unsigned ints sind.

    unskilled schrieb:

    auf jeden fall ist der cast von oben nicht all zu ungefährlich... (der vom pow-ergebnis nach uint)

    Was ist daran gefährlich?

    unskilled schrieb:

    ich find schon allein uint komisch - was ist das fürn typedef?

    Tja, was wird uint wohl für ein typedef sein, wenn b und e unsigned ints sind.. 🙄

    Ich werde mir bestimmt keine eigene Funktion schreiben, wenn es 1. bereits eine in der CRT Library gibt und 2. diese vermutlich optimiert ist.



  • warnerBros schrieb:

    unskilled schrieb:

    um das zu wissen solltes du evtl erst mal sagen, was du machen willst und dann wüsste vll jmd nen besseren weg...

    Habe ich bereits gesagt. b^e, wobei beides unsigned ints sind.

    stimmt, hab ich übersehen - naja, ich mag so ne typedefs absolut nicht - aber bei (mind.) 32bit als exponent kannst du dir ja selbst zusammenreimen, wieso der cast von float nach int dann gefährlich sein könnte...

    warnerBros schrieb:

    Ich werde mir bestimmt keine eigene Funktion schreiben, wenn es 1. bereits eine in der CRT Library gibt und 2. diese vermutlich optimiert ist.

    ich denke die von camper wird schneller sein als das, was du bisher machst...

    bb



  • warnerBros schrieb:

    Ich werde mir bestimmt keine eigene Funktion schreiben, wenn es 1. bereits eine in der CRT Library gibt und 2. diese vermutlich optimiert ist.

    Ja, die ist optimiert. Aber auf float. Und die Potenz mit floats ist deutlich schwieriger als mit int und dauert dementsprechend länger.



  • unskilled schrieb:

    stimmt, hab ich übersehen - naja, ich mag so ne typedefs absolut nicht -

    Aha... 🙄

    unskilled schrieb:

    aber bei (mind.) 32bit als exponent kannst du dir ja selbst zusammenreimen, wieso der cast von float nach int dann gefährlich sein könnte...

    Wenn float selber 32 bit ist, kann der Exponent alleine kaum mind. 32 Bit sein.
    Meine Casts sind ungefährlich, weil meine Zahlen alle recht klein sind (alle < 10, also sowas wie powi(3, 4) etc))

    unskilled schrieb:

    ich denke die von camper wird schneller sein als das, was du bisher machst...

    Aus der MSDN:

    pow has an implementation that uses Streaming SIMD Extensions 2 (SSE2).

    Ich bezweifle stark, dass campers Funktion schneller ist, als eine SSE2
    optimierte 😉
    Es geht auch ums Prinzip. Wenn es eine fertige Funktion gibt, die meinen Fall abdecken kann, dann nehme ich die.



  • dann machs halt weiterhin so...
    "Wenn float selber 32 bit ist, kann der Exponent alleine kaum mind. 32 Bit sein." doch: uint e -> unsigned int e -> mind. 32bit

    "meine Zahlen alle recht klein sind (alle < 10, also sowas wie powi(3, 4) etc))" jede wette, dass pow dann langsamer ist als campers pow...

    "Es geht auch ums Prinzip. Wenn es eine fertige Funktion gibt, die meinen Fall abdecken kann, dann nehme ich die."
    offensichtlich gibt es eben keine pow-überladung für integer
    aber ich merks schon, ist rel. sinnlos hier was zu sagen...

    hf gl



  • Wenn wird gerade dabei sind; ein weiterer schulmathematischer Weg zum Potenzieren vorzeichenloser Ganzzahlen:

    #include <iostream>
    
    typedef unsigned int uint_t;
    
    uint_t pow(uint_t base, uint_t exponent);
    
    int main()
        {
            std::cout << "pow( 6u, 9u ) = " << pow(6u, 9u) << std::endl;
        }
    
    uint_t pow(uint_t base, uint_t exponent)
        {
            if(exponent == 0u) return 1u;
            return base * pow(base, exponent - 1u);
        }
    

    Grüße... Heiko



  • bwbg schrieb:

    Wenn wird gerade dabei sind; ein weiterer schulmathematischer Weg zum Potenzieren vorzeichenloser Ganzzahlen:

    #include <iostream>
    
    typedef unsigned int uint_t;
    
    uint_t pow(uint_t base, uint_t exponent);
    
    int main()
        {
            std::cout << "pow( 6u, 9u ) = " << pow(6u, 9u) << std::endl;
        }
    
    uint_t pow(uint_t base, uint_t exponent)
        {
            if(exponent == 0u) return 1u;
            return base * pow(base, exponent - 1u);
        }
    

    Grüße... Heiko

    Und dazu campers speed-Trick mischen.

    #include <iostream>
    
    typedef unsigned int uint_t;
    
    uint_t pow(uint_t base, uint_t exponent);
    
    int main()
        {
            std::cout << "pow( 6u, 9u ) = " << pow(6u, 9u) << std::endl;
        }
    
    uint_t pow(uint_t base, uint_t exponent)
        {
            if(exponent == 0u) return 1u;
            if(exponent % 2u == 0u) return square(pow(base, exponent / 2u));
            return base * pow(base, exponent - 1u);
        }
    


  • Ich tendiere auch zu der eigenen Lösung.

    Jedoch noch ein Hinweis zu der Warnung bzgl. dem möglichen Datenverlust (bzw. Rundungsfehler).
    Mittels

    int i = 0;
    while(i == static_cast<int>(float(i)))
      i++;
    

    läßt sich ermitteln, ab welchem Wert sich eine Ganzzahl nicht mehr exakt als float darstellen läßt. Ich meine, dies wäre erst bei mehr als 10 Mio. (habe jetzt leider keinen Compiler hier am Rechner).

    Jedoch sollte man beide Lösungen auch auf einen möglichen Überlauf testen, z.B. würde pow(2, 32) ja schon in der "uint"-Variante 0 als Ergebnis ergeben (sofern uint 32 bit groß ist)...


Anmelden zum Antworten