Multiplikation mit Integern



  • Nee, mit long ändert sich am Ergebnis auch nichts, nur wenn ich nach float oder double ändere. Aber das ist ja genau meine Frage ?!



  • ser1al_ausgeloggt schrieb:

    WoWe schrieb:

    Hi,

    warum funktioniert eine einfache Multiplikation mit Integern nicht ? Mir ist schon klar wenn es um eine Division geht, dass ich dann mit float oder double arbeiten muss. Aber wenn ich nur Ganzzahlen multiplizieren will ... 😕


    Bei folgendem Beispiel bekomme ich einen total falschen Wert geliefert ( 370.632.704)***

    int pix;
    int X, Y, Res;
    
    X = 90;
    Y = 100;
    Res = 720;
    
    pix = X * Res * Y * Res;
    

    Muss ich bei Ganzzahl Multiplikationen immer auf float oder double umwandeln ?

    was heißt denn "geht nicht"?
    bitte fehler oder ergebnis sagen!...

    😕 😕

    Gruß,

    Simon2.



  • naja probiere mal folgendes

    std::cout << sizeof(int) << std::endl;
    std::cout << sizeof(long) << std::endl;
    

    erklärt dir bestimmt warum es kein Unterschied macht denke da kommst selbst drauf 🙂



  • WoWe schrieb:

    Nee, mit long ändert sich am Ergebnis auch nichts, nur wenn ich nach float oder double ändere. Aber das ist ja genau meine Frage ?!

    vermutlich ist std::numeric_limits<long>::max() == std::numeric_limits<int>::max() bei dir und beide sind zu klein für das Ergebnis. Nimm also entweder unsigned long, long long (bzw. _Longlong) oder std::int64_t (aus <cstdint>)

    Und gewöhne dir an sinnvolle Fehlerbeschreibungen zu liefern 👎



  • Danke für eure Tips. Wahr doch der Wertebereich. Ich hatte es am Anfang mal nur für pix mit __int64 probiert, gleicher Fehler. Erst wenn ich alle Variablen nach __int64 ändere kommt das richtige Ergebnis raus.



  • WoWe schrieb:

    Nee, mit long ändert sich am Ergebnis auch nichts, nur wenn ich nach float oder double ändere. Aber das ist ja genau meine Frage ?!

    Das Ergebnis ist zu groß für eine 32Bit-Variable. Ein int kann als größte Zahl 2^32-1 annehmen. Das echte Ergebnis - (2^32-1) ist gerade der von Dir erhaltene Wert. Da hilft nix, Du mußt auf ne größere Variable umsteigen. Dass long nicht funktioniert legt nahe, dass long bei Dir ebenfalls 32 Bit hat. Probier doch mal long long, das hat zumindest auf meiner Plattform ne Größe von 64 Bit und damit reichlich Platz für das Ergebnis.

    MfG Jester



  • Das Ergebnis ist unter Berücksichtigung der Datentypgröße vollkommen richtig...

    Selbst long ist auf vielen Systemen nur 4 Byte, und dann ist der Maximalbereich nunmal –2.147.483.648 bis 2.147.483.647. Die Zahl die du Darstellen willst ist aber die Zahl 4.665.600.000 die selbst wenn du unsigned long nimmst noch immer nicht im Bereich des Wertes ist. Die Rechnung mit Gleitkommazahlen kann je nach Stellengenauigkeit aber ebenso problematisch sein (Mit krummeren Werten dürfte es bald an die Grenzen kommen, je nach Typ und System).

    Wenn bereits der Typ "long long" bei dir läuft, nimm den (Auf diesen System hier 8 Byte; Was 18-19 Stellen Genauigkeit wären).

    cu André



  • WoWe schrieb:

    Danke für eure Tips. Wahr doch der Wertebereich. Ich hatte es am Anfang mal nur für pix mit __int64 probiert, gleicher Fehler. Erst wenn ich alle Variablen nach __int64 ändere kommt das richtige Ergebnis raus.

    es reicht auch pix als 64Bit Integer zu nehmen und einen Faktor zu casten. (btw __int64 ist nicht standard konform, schau dir lieber std::tr1::int64_t aus <cstdint> an, wenn dein Compiler den TR1 beherrscht)



  • rüdiger schrieb:

    ...
    Und gewöhne dir an sinnvolle Fehlerbeschreibungen zu liefern 👎

    Sorry - eigentlich gehöre ich da auch zu den Mahnern, aber was ist hier denn konkret auszusetzen:

    WoWe schrieb:

    ...
    Bei folgendem Beispiel bekomme ich einen total falschen Wert geliefert ( 370.632.704)...

    ?

    Gruß,

    Simon2.



  • Simon2 schrieb:

    rüdiger schrieb:

    ...
    Und gewöhne dir an sinnvolle Fehlerbeschreibungen zu liefern 👎

    Sorry - eigentlich gehöre ich da auch zu den Mahnern, aber was ist hier denn konkret auszusetzen:

    WoWe schrieb:

    ...
    Bei folgendem Beispiel bekomme ich einen total falschen Wert geliefert ( 370.632.704)...

    ?

    Gruß,

    Simon2.

    Hallo Simon2,

    sehe ich genauso wie Du, bin mir keiner Verletzung der Form bewusst.

    Nochmal zum Thema. Mit allen Variablen nach long long geht es, aber wenn ich nur pix als long long habe und caste funktioniert es auch nicht. Hab ich da was falsch verstanden ?

    long long pix;
    int X, Y, Res;
    
    X = 90;
    Y = 100;
    Res = 720;
    
    pix = static_cast<long long>(X * Res * Y * Res);
    


  • Du darfst nicht erst danach casten. Die Berechnung wird immer im genausten Typ der beteiligt ist durchgeführt. Eine nachfolgende Umwandlung bietet keine erhöhte Genauigkeit mehr.

    pix = static_cast<long long>(X)*Res*Y*Res;
    

    Zwing den Compiler alles in long long zu rechnen, da der Faktor static_cast<long long>(X) ein long long ist.



  • WoWe schrieb:

    Hab ich da was falsch verstanden ?

    Ich wuerde eher sagen nicht genau gelesen:

    es reicht auch pix als 64Bit Integer zu nehmen und einen Faktor zu casten.

    Du castest das Ergebnis, welches noch den urspruenglichen Datentyp hat. Damit hat der Ueberlauf schon stattgefunden.

    Gruss,
    DeSoVoDaMu



  • Prima ! Vielen Dank für die Erklärung.



  • Simon2 schrieb:

    ser1al_ausgeloggt schrieb:

    WoWe schrieb:

    Hi,

    warum funktioniert eine einfache Multiplikation mit Integern nicht ? Mir ist schon klar wenn es um eine Division geht, dass ich dann mit float oder double arbeiten muss. Aber wenn ich nur Ganzzahlen multiplizieren will ... 😕


    Bei folgendem Beispiel bekomme ich einen total falschen Wert geliefert ( 370.632.704)***

    int pix;
    int X, Y, Res;
    
    X = 90;
    Y = 100;
    Res = 720;
    
    pix = X * Res * Y * Res;
    

    Muss ich bei Ganzzahl Multiplikationen immer auf float oder double umwandeln ?

    was heißt denn "geht nicht"?
    bitte fehler oder ergebnis sagen!...

    😕 😕

    Gruß,

    Simon2.

    oops, sorry!
    Hab ich echt übersehen 😞


Anmelden zum Antworten