源代码是这样的,乍一看的很难的,但其实仔细去解剖还是很好理解的
float RadicalInverse_VdC(uint bits)
{
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}
假设位置顺序为(我们这里不用0方便理解)且假设每位都为1(真)
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32
第一步, bits = (bits << 16u) | (bits >> 16u);,把前移十六位 | 后移十六位
那么就是
17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32(后面的位是补0的,一共是16位0,我们不算)
|
(前面面的位是补0的,一共是16位0,我们不算) 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
那么就变成了
17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
第二步,bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
5的二进制位是0101那么就是奇数位1,3,5,7,9…进行前移一位,移到偶数位
变成
18,0,20,0,22,0,24,0,26,0,28,0,30,0,32,0,2,0,4,0,6,0,8,0,10,0,12,0,14,0,16,0
|
A的二进制位是1010,也就是偶数位,进行后移,移到奇数位
变成
0,17,0,19,0,21,0,23,0,25,0,27,0,29,0,31,0,1,0,3,0,5,0,7,0,9,0,11,0,13,0,15
结果为
18,17,20,19,22,21,24,23,26,25,28,27,30,29,32,31,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15
接下来两步就不这样写了,太累了,哈哈
第三步 bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
3是0011 ,C是1100
那么就是每4位的后两位前移 | 前两位后移
变成
20,19,18,17,24,23,22,21,28,27,26,25,32,31,30,29,4,3,2,1,8,7,6,5,12,11,10,9,16,15,14,13
第四步 bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
F是1111,0是0000,0F是00001111,F0是11110000
那么就是每8位是后四位前移 | 前四位后移
变成
24,23,22,21,20,19,18,17,32,31,30,29,28,27,26,25,8,7,6,5,4,3,2,1,16,15,14,13,12,11,10,9
第五步 bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
00FF是0000000011111111,FF00是1111111100000000
那么就是每16位的后八位前移 | 前八位后移
变成
32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1
这样就完成了翻转
但是浮点数的范围是有负数的,这样虽然完成了按位反转,但读出的数不是正确的,我们需要这些数规定在0~1之间,所以乘以了* 2.3283064365386963e-10这个数,但是我只知道为什么乘这个数。
不知道这个数的原理,大家有知道的也可以评论给我,哈哈,让我也填下这个坑
以上就是Van Der Corput 序列的内容了
还请帮忙给个赞支持一下,你的点赞是我写作的动力!