7

发现自己正在查看 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
4

2 回答 2

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

于 2015-05-28T14:27:56.653 回答
1

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

于 2015-05-28T14:30:29.200 回答