“通用”的外表是神奇的,“通用”的内心是神秘的。
假设某系统(如STM32芯片)的某特殊n bit内存块(如某寄存器),最高x(x属于[0, n])bit保存最大为Lmax的男生数量,最低y(y = n - x)bit用来保存最大为Mmax的女生数量。当确定了男女生的最大数Lmax,Mmax时,如何将男生数量L(L属于[0, Lmax])和女生数量M(M属于[0, Mmax])准确的保存在这n bit中?这种情况在配置寄存器中常见,如配置中断优先级相关的寄存器时。
Lmax |
Mmax |
Lbmax |
Mbmax |
0 |
15 |
0 |
4 |
1 |
7 |
1 |
3 |
4 |
4 |
2 |
2 |
7 |
1 |
3 |
1 |
15 |
0 |
4 |
0 |
现在要实现在告知Mbmax的情况下,就能够将L(L是男生数),M(M是女生数)准确的将L,M保存在这4bit中的准确位置中。
[1] 用Mbmax来移除L不应在4 bit中的位。
[2] 用Mbmax来保留M只该被保留的位。
uint_32 tmp = 0x00; tmp = L << Mbmax; tmp |= M & Mmax; weekend = tmp << 28;
1~3. L和M为给定的男女数,若L和M分别在[0, Lmax]和[0, Mmax]中即L和M没有超过在内存中应占的最大位数时,L和M值被正确地保存在tmp的bit[4:0]的最高Lbmax,最低Mbmax位中。若L或M不在以上范围之内,则最高Lbmax及最低Mbmax位中保存的都是1即保存的是Lmax和Mmax。
4. 若weekend寄存器的bit[31:28]位需要如此的配置,则将tmp移位到左移28位赋值给weekend时就能够达目标。
现有[0, L]这样一组正整数。每m个分为一组,即[0, m -1]为第0组,[m, 2m -1]为第1组……对于得到的每一个组,从第一个元素开始编号为0, 1, …, m – 1。n >= 2m – 1,m为大于0的正整数。
[1] 元素x(x属于[0, L])在哪一个组?
[2] 元素x的编号?
[1] 元素x属于 |_ x / m _|组。|_ x / m _|为x除以m的商。
[2] 元素x的编号为x % m(x除以m的余数)。特殊的,当m为2^k(k = 0, 1, 2…)时,考虑第y(y属于[2, |_ L / m _| + 1])组的元素数与(y – 1)组的元数在内存中的存储的区别:同编号的元素的最低k bit相同,第y组元素的第(k + 1)bit为1,第(y - 1)组元素的第(k + 1)bit为0。第一组元素即为编号。这就是说,此时要求的x的编号就是x & (2^k– 1)。
//x所在的组数 group = x >> 0x05; //x的编号 index = x & 0x1f;