阅读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等价。