kleines rätsel...



  • wieso ist abs(-2147483648) auf i386ern nicht definiert ?



  • weil der positive Wert +2147483648 nicht ganz in den Wertebereich eines int reinpasst 😉



  • punktrichter schrieb:

    sothis_ schrieb:

    abs(-2147483648) ist auf i386 architekturen nicht definiert

    kann man gelten lassn. genauer gesagt, der wert INT_MIN lässt sich nicht positiv machen, weil zweierkomplement irgendwie doch nicht so toll ist.
    der diesjährige titel: 'bester c-programmierer des universums' geht damit an...

    ---> sothis_

    🙂

    YAY! 😃



  • CStoll schrieb:

    weil der positive Wert +2147483648 nicht ganz in den Wertebereich eines int reinpasst 😉

    ja, hast recht, jetzt seh ichs auch 😃
    müsste man den rückgabetypen unsigned int machen.
    🙂



  • das allein würde noch nicht reichen, da sämtliche abs() implementationen
    direkt mit dem eingabetyp operieren (i.e. int in ein register kopieren und
    dann das zweierkomplement berechnen). auf 32bit architekturen gestaltet sich
    das ganze dann einwenig komplizierter 🙂



  • au haua aua, also v 🙂 orher den wert in eine unsigned int variable reinkopieren.



  • oha krass schrieb:

    au haua aua, also v 🙂 orher den wert in eine unsigned int variable reinkopieren.

    <stuss detected at monday 14.01.08 15:29>



  • oha krass schrieb:

    au haua aua, also v 🙂 orher den wert in eine unsigned int variable reinkopieren.

    Nützt auch nicht sehr viel - wenn du einen negativen Wert in den unsigned kopierst, erhältst du einen (meist recht großen) positiven Wert - und mit dem kann abs wohl nicht sehr viel anfangen.

    (signed int verwendet das erste Bit als Vorzeichen, unsigned int als höchstwertiges Bit der Darstellung)



  • <stuss detector active schrieb:

    <stuss detected at monday 14.01.08 15:29>

    oja, ich hirnie 🙄
    aber so könnts gehen:
    if (x < 0 && x > -2147483648) 🙂



  • ha ! noch nen blitzemerker geistesblitz !
    man könnt den wert in einen double kopieren 🙂
    tadaaaaaaa 👍



  • achsooo schrieb:

    <stuss detector active schrieb:

    <stuss detected at monday 14.01.08 15:29>

    oja, ich hirnie 🙄
    aber so könnts gehen:
    if (x < 0 && x > -2147483648) 🙂

    Und was machst du, wenn jemand tatsächlich den Betrag von INT_MIN haben möchte 😉

    ajoooo schrieb:

    man könnt den wert in einen double kopieren 🙂

    möglich, aber nicht gerade optimal - je nach System könntest du dir bei der Umwandlung einige ärgerliche Rundungsprobleme einhandeln (ja, der Wertebereich von double ist ein Stück größer, aber die Genauigkeit ist begrenzt).



  • CStoll schrieb:

    Und was machst du, wenn jemand tatsächlich den Betrag von INT_MIN haben möchte 😉

    ich dachte an den weg, über double zu gehen.
    also int->double->unsigned int
    scheint mir auch recht umständlich, aber vielleicht immer noch besser als gar keine möglichkeit. ( wenn man denn sowas mal brauchen sollte )

    CStoll schrieb:

    möglich, aber nicht gerade optimal - je nach System könntest du dir bei der Umwandlung einige ärgerliche Rundungsprobleme einhandeln (ja, der Wertebereich von double ist ein Stück größer, aber die Genauigkeit ist begrenzt).

    naja, aber int ist doch ein ganzzahltyp, da braucht man doch nichts zu runden. 🙂



  • jippjipp schrieb:

    naja, aber int ist doch ein ganzzahltyp, da braucht man doch nichts zu runden. 🙂

    int schon, double nicht 😉 (und bei so großen Zahlen kann es durchaus vorkommen, daß sie nicht mehr exakt in einen double passen)



  • CStoll schrieb:

    und bei so großen Zahlen kann es durchaus vorkommen, daß sie nicht mehr exakt in einen double passen

    das wird ja von unsigned int wieder glatt gebügelt 🙂



  • _________________________ schrieb:

    CStoll schrieb:

    und bei so großen Zahlen kann es durchaus vorkommen, daß sie nicht mehr exakt in einen double passen

    das wird ja von unsigned int wieder glatt gebügelt 🙂

    Nein, wird's nicht - wenn bei der Umwandlung in double die letzte Stelle gerundet wurde, ist sie weg und kann bei der Rückumwandlung auch nicht zurückgeholt werden.



  • unsigned int abs_strangesome( double a )
    {
    	if ( a < 0 )
    		a *= -1;
    	return a;
    }
    
    int main()
    {
    	printf("%u\n", abs_frickelei(-2147483648) );
    	return 0;  
    }
    

    ausgabe, wer hätte das gedacht 😃
    2147483648



  • CStoll schrieb:

    ... wenn bei der Umwandlung in double die letzte Stelle gerundet wurde, ...

    IMHO werden die Stellen immer abgeschnitten, nie gerundet. Sonst müßte ja eine Stelle mehr ausgerechnet werden, als in das Zielformat paßt. Statistisch verschlimmert das ja auch den Fehler nicht ...



  • abs warrior schrieb:

    ausgabe, wer hätte das gedacht
    2147483648

    double ist doch doof. double kann eventuell viel zeit kosten. besser wäre 'long long' (das spinnt dann erst bei LLONG_MIN). aber was wirklich zickt, ist nicht der wertebereich, sondern das zweierkomplement-verfahren. mit einerkomplement gäbe es kein problem (nur hat man dann eben zwei nullen).
    🙂


Anmelden zum Antworten