2015-05-28 10 views
6

fand ich auf der arc4random_uniform Quelle sucht (http://bxr.su/o/lib/libc/crypt/arc4random_uniform.c)Modulus Operator vs Null (re: arc4random_uniform Quelle)

Meine Frage an die folgenden Zeile betrifft (der Kommentar ist ihr ursprünglicher Kommentar):

/* 2**32 % x == (2**32 - x) % x */ 
min = -upper_bound % upper_bound; 

Nun, ich bin kein Mathematikgenie, aber sicherlich wird -N% N immer gleich Null. Also, warum schreiben Sie nicht nur

min=0 
+2

Related: http://StackOverflow.com/Questions/8026694/c-Unary-Minus-Operator-Behavior-with-unsigned-operands – dragosht

Antwort

4

Es ist wichtig zu beachten, dass wir mit unsigned ints zu tun hat (uint32_t) hier, so -upper_bound nicht tut, was Sie denken, es tut. Es ist tatsächlich , wegen modulo wrap-around, und der Zweck dieser wird in der obigen Kommentar erklärt (d. H. Erhalt 2**32 % upper_bound ohne Überlauf).

Beispiel:

#include <stdio.h> 
#include <stdint.h> 

int main() 
{ 
    uint32_t upper_bound = 42; 
    uint32_t min = -upper_bound % upper_bound; 
    printf("%u -> %u\n", upper_bound, min); 
    return 0; 
} 

gibt:

42 -> 4 

LIVE CODE

1

Zunächst ist es erwähnenswert, dass die Variablen uint32_t sind, also ohne Vorzeichen. Dann schauen wir genauer hin: -upper_bound % upper_bound = (-upper_bound) % upper_bound;. Es bedeutet, dass -upper_bound eigentlich das 2er-Komplement von upper_bound ist. Angenommen, upper_bound=10, dann -upper_bound ist 0xFFFFFFF6=246. Dann -upper_bound % upper_bound = 246%10 = 6. Und du kannst es testen.