模数运算符与零(re:arc4random_uniform source)

时间:2015-05-28 14:15:08

标签: c math cryptography openbsd type-bounds

发现自己正在查看arc4random_uniform源(http://bxr.su/o/lib/libc/crypt/arc4random_uniform.c

我的问题涉及以下一行(评论是他们的原始评论):

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

现在,我没有数学天才,但肯定-N%N总是等于零。那么为什么不写呢

min=0

2 个答案:

答案 0 :(得分:5)

重要的是要注意我们在这里处理无符号整数(uint32_t),因此-upper_bound不会按照您的想法执行。它实际上是2**32 - upper_bound,由于模数环绕,其目的在上面的注释中解释(即获得2**32 % upper_bound而没有溢出)。

示例:

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

给出:

42 -> 4

LIVE CODE

答案 1 :(得分:1)

首先,值得一提的是变量是uint32_t,因此是无符号的。然后让我们仔细看看: -upper_bound % upper_bound = (-upper_bound) % upper_bound;。这意味着-upper_bound实际上是upper_bound的补充。假设upper_bound=10,则-upper_bound0xFFFFFFF6=246。然后是-upper_bound % upper_bound = 246%10 = 6。你可以测试它。