Per Christensen noted the following. (Text slightly edited.)
I came across an issue with the PermutedRadicalInverse() function from the 2nd edition. To explain the issue as simply as possible, assume we’re computing in base 2 and the permutation array p is {1,0} so ones get converted to zeroes and vice versa. (I know that for the particular case of base 2 there are much more efficient ways of doing digit scrambling using e.g. bit-wise xor, but let’s ignore that for now.)
Here’s my version of your function — pretty much verbatim straight out of the book:
float
PermutedRadicalInverse(unsigned n, const unsigned base, unsigned *perm)
{
float val = 0.0f;
float invBase = 1.0f / base, invBi = invBase;
while (n > 0) {
unsigned d_i = perm[n%base];
val += d_i * invBi;
n *= invBase;
invBi *= invBase;
}
return val;
}
The results I get for n=0..15 are not what I’d expect:
There are several repeats of 0 and 0.5. It seems to me that the issue is that the loop exits too early — just because n is 0 doesn’t mean we can skip the rest of the digits. Here is a slightly modified version that loops over all digits to give them a chance to be permuted into non-zero values:
float
PermutedRadicalInverseBetter(unsigned n, const unsigned base, unsigned *perm)
{
float val = 0.0f;
float invBase = 1.0f / base, invBi = invBase;
for (unsigned d = 0; d < 32; d++) { // loop over all digits
unsigned d_i = perm[n%base];
val += d_i * invBi;
n *= invBase;
invBi *= invBase;
}
return val;
}
With this change I get the following values (which seem more reasonable):
Per Christensen noted the following. (Text slightly edited.)
I came across an issue with the PermutedRadicalInverse() function from the 2nd edition. To explain the issue as simply as possible, assume we’re computing in base 2 and the permutation array p is {1,0} so ones get converted to zeroes and vice versa. (I know that for the particular case of base 2 there are much more efficient ways of doing digit scrambling using e.g. bit-wise xor, but let’s ignore that for now.)
Here’s my version of your function — pretty much verbatim straight out of the book:
The results I get for n=0..15 are not what I’d expect:
There are several repeats of 0 and 0.5. It seems to me that the issue is that the loop exits too early — just because n is 0 doesn’t mean we can skip the rest of the digits. Here is a slightly modified version that loops over all digits to give them a chance to be permuted into non-zero values:
With this change I get the following values (which seem more reasonable):