2015-05-28 15 views
6

ritrovai a guardare il sorgente arc4random_uniform (http://bxr.su/o/lib/libc/crypt/arc4random_uniform.c)Modulo Operatore vs Zero (re: fonte arc4random_uniform)

mia domanda riguarda la riga seguente (il commento è la loro commento originale):

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

Ora, non sono un genio della matematica, ma sicuramente -N% N sarà sempre uguale a zero. Allora perché non basta scrivere

min=0 
+2

Correlati: http://stackoverflow.com/questions/8026694/c-unary-minus-operator-behavior-with-unsigned-operands – dragosht

risposta

4

E 'importante notare che abbiamo a che fare con unsigned int (uint32_t) qui, in modo da -upper_bound non fa quello che pensi lo fa. In realtà è , a causa del wrap-around del modulo e lo scopo è spiegato nel commento sopra (ad esempio ottenendo 2**32 % upper_bound senza overflow).

Esempio:

#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; 
} 

dà:

42 -> 4 

LIVE CODE

1

Innanzitutto vale la pena ricordare che le variabili sono uint32_t, quindi senza segno. Quindi guardiamo da vicino: -upper_bound % upper_bound = (-upper_bound) % upper_bound;. Significa che -upper_bound è in realtà il complemento a 2 di upper_bound. Supponiamo che upper_bound=10, quindi -upper_bound sia 0xFFFFFFF6=246. Quindi -upper_bound % upper_bound = 246%10 = 6. E puoi provarlo.