rand liefert negative-werte !!!



  • Hallo Forum,

    rand() % 256; /* eigene Zufalls-ID     */
    

    leider erhalte ich teilweise negative Werte !
    Wie kann ich das verhindern ?

    mfg Oliver Kern.



  • Zeigstn du bitte den orginal Code die Zeile mit dem rand plus die 5 Zeile davor und danach, sowie alle Variablendeklarationen die beim rand benutzt werden.

    Benutzt du srand einmal am Anfang um alles zu initialisieren

    Ich würde an dieser Stelle eher zum bitweiseen & als zum Modulo Operator greifen.

    unsigned int p;
    ......
       /* Seed the random-number generator with current time so that
        * the numbers will be different every time we run.
        */
       srand( (unsigned)time( NULL ) );
    ......
    p=(unsigned int)rand() & 0xff;
    .........
    


  • hi

    versuchs mit

    p=(int)(256.0*rand()/257.0);
    

    hoff es hilft



  • @dawn:
    Für dein Bsp mal bitte aus, ich versteh den sin nit.
    wie soll das negative Werte verhindern?? Wenn dann währe quadrieren und danach sqrt mathematisch der richtige weg.

    @daa531 zu PAD gibts nix hinzuzufügen meinerseits

    @PAD ist die Bit-Variante schneller als Modulo?



  • Ich vermute es da anstelle 1*Division, 1*Multiplikation und 1*Subtraktion, nur ein Bitweise AND vorgenommen werden muß und das bitweise AND in den meisten Processoren als eigenständiger Befehl implementiert ist.

    Modulo:
    a % b = a-(int)((int)a / int(b))*b

    Bei modernen Processoren könnte der Unterschied unerheblich sein, bei embedded Porcessoren/Systemen (8/16 Bit) ist er vorraussichtlich relevant.



  • Schlaue (dh. übliche) Compiler übersetzen modulo Zweierpotenz automatisch in ein entsprechendes AND. Jedenfalls konnte das Turbo C++ vor 10 Jahren, warum sollten heutige Compiler dümmer sein.



  • @ Bashar, damit hast du mich verblüfft. Ich habs jetz mit Visual C++ 6.0 ausprobiert und folgende
    Ergebnisse bekommen:

    Sind die Variablen int:
    ; 146  : 	peter=i % 256;
    mov	 ecx, DWORD PTR _i$[ebp]
    and	 ecx, -2147483393	; 800000ffH
    jns	 SHORT $L1173
    dec	 ecx
    or	 ecx, -256		; ffffff00H
    inc	 ecx
    $L1173:
    mov	 DWORD PTR _peter$[ebp], ecx
    
    Sind die Variablen unsigned int:
    ; 146  : 	peter=i % 256;
    mov	 eax, DWORD PTR _i$[ebp]
    xor	 edx, edx
    mov	 ecx, 256		; 00000100H
    div	 ecx
    mov	 DWORD PTR _peter$[ebp], edx
    
    Und die Lösung mit &
    ; 149  : 		peter=i & 0xff;
    mov	 edx, DWORD PTR _i$[ebp]
    and	 edx, 255		; 000000ffH
    mov	 DWORD PTR _peter$[ebp], edx
    


  • Release-Version und auf Geschwindigkeit optimiert?



  • sowohl als auch, hier ist die debug Version zu sehen. Der unterschied zur release version ist das die Releaseversion die Daten nicht explizit holt sondern hier die register besser nutzt, die prinzipielle Algorythmik war identisch

    Trotzdem Gute Idee mit der Nachfrage.



  • Vielen Dank an alle die gepostet haben !

    Ich haette die vollstaendige Codezeile schreiben sollen.
    Hier ist diese:

    cirpoi->ideige = rand() % 256; /* eigene Zufalls-ID     */
    

    ideige -> char = nimmt werte von -128 bis 128
    geaendert in
    ideige -> unsigned char = nimmt werte von 0 bis 128

    Auch wenn rand einen negativen Wert ausgibt wird bei unsigend char
    ein positiver Wert daraus.
    Wenn ich nicht richtig liege, bitte um Aufklaerung, danke.

    mfg Oliver Kern.



  • daa531 schrieb:

    Auch wenn rand einen negativen Wert ausgibt wird bei unsigend char ein positiver Wert daraus.

    Andersrum. rand gibt nur positive Werte raus, aber dadurch, dass du den Wert in einem vorzeichenbehafteten Typ ablegst (char ist bei dir offensichtlich signed), werden manche Werte negativ.

    Wenn ich nicht richtig liege, bitte um Aufklaerung, danke.

    Bitte.



  • PAD schrieb:

    Ich vermute es da anstelle 1*Division, 1*Multiplikation und 1*Subtraktion, nur ein Bitweise AND vorgenommen werden muß und das bitweise AND in den meisten Processoren als eigenständiger Befehl implementiert ist.

    Modulo:
    a % b = a-(int)((int)a / int(b))*b

    Bei modernen Processoren könnte der Unterschied unerheblich sein, bei embedded Porcessoren/Systemen (8/16 Bit) ist er vorraussichtlich relevant.

    Auch 8 bit Prozessoren unterstützen in der Regel eine Modulo Operation. Mir ist kein Prozessor bekannt, der sie nicht unterstützt. Und wenn es tatsächlich einen gibt, der kein Modulo unterstützt, dann wird dieser höchstwahrscheinlich auch keine Division unterstützen.


Anmelden zum Antworten