timrau が指摘したように、これは 2 の補数です。答えを知っていれば (私のように) 答えを見つけるのは簡単ですが、導き出すのは困難です。
コピーされた部分から始めます。
copy_mask = a ^ (a - 1) // extract rightmost 1 and smear to the right
明らかに、コピーされていない部分 (つまり、あなたが呼んだように「否定」された部分) は、単にそのマスクの補数です。
negated_mask = ~copy_mask
そして今、私たちは構築することができますb
:
b = (a & copy_mask) | (~a & ~copy_mask)
代わりの:
b = (a & (a ^ (a - 1))) | (~a & ~(a ^ (a - 1)))
簡素化する:
// move complement into xor
b = (a & (a ^ (a - 1))) | (~a & (a ^ ~(a - 1)))
// use two's complement definition
b = (a & (a ^ (a - 1))) | (~a & (a ^ -a))
// use two's complement definition
b = (a & ~(a ^ -a)) | (~a & (a ^ -a))
// use definition of xor: p^q = (p&~q)|(~p&q)
b = a ^ (a ^ -a)
// use xor associativity
b = (a ^ a) ^ -a
// simplify xor with self
b = -a
あまりにも多くのステップをスキップしない、より短い方法がおそらくあります..