Irrlight中位移运算

阅读Irrlight源代码,看到下面这样一个函数,从注释上看它是由condition来决定设置还是清除mark的一个快速实现,一时好奇就探究了一下它是怎样实现的

/*
        if (condition) state |= m; else state &= ~m;
    */
    REALINLINE void setbit_cond ( u32 &state, s32 condition, u32 mask )
    {
        // 0, or any postive to mask
        //s32 conmask = -condition >> 31;
        state ^= ( ( -condition >> 31 ) ^ state ) & mask;
    }

核心代码可以被分解,

state = state ^ ( (-c >> 31) ^ s ) & m

同时有两个关于异或的定理,

1 ^ A = A ^ 1 = 1 and (! A) 与 0 ^ A = A ^ 0 = 1 and A

-condition >> 31这个表达式,用来取32位整数的符号位,当condition大于0时,这个表达式值为1,反之为0。下面开始分类证明:

如果conditon>0,则表达式为(1^state),把它展开为1 and (!state),

如果state>0, 则表达式为state ^ 0 & mask,因为state>0,所以1 and state & mask = state & mask

如果state=0,则表达为state^ 1 & mask,因为state=0,所以1 and (!state) & mask = mask

所以综上所述,如果condition>0,表达式的结果与state & mask等价;

如果condition<0,则表达为(0^state),把它展开为1 and state,

如果state > 0,则表达式state ^ 1 & mask,展开为1 and (!state),因为state>0,所以1 and (!state) & mask = state ^ mask,因为state>0,所以state and !m,

如果state = 0,则表达式stae ^ 0 & mask,展开为1 and state & mask,因为state=0,所以0 & mask = 0

综上所述,如果contion<0,表达式的结果与state and !m等价。

原文地址:https://www.cnblogs.com/BlankEye/p/2911038.html