csapp 习题 - 如何实现异或 exclusive-or

阅读 csapp v3 时,练习题 2.13 颇有意思。练习题描述以下。app

位设置是对于参数 mask 中每个为 1 的位,那么参数 x 中相应位则被设置为 1 ;位清除是对于参数 mask 中每个为 1 的位,那么参数 x 中相应位则被设置为 0 。假设有两个函数 bis 和 bic 来实现位设置和位清除,请使用这两个函数实现两个数的异或结果。函数

小提示:可使用的位运算是测试

local function bis(x, mask)
	return x | mask
end

local function bic(x, mask)
	return x & ~mask
end

什么是异或呢?异或就是两个值中,至少有一个为真,但不全为真,那么结果就是真,不然结果就是假。对于两个二进制位,至少有一个位为 1 但不全为 1,那么结果就是 1,不然结果是 0 。
也就是说只有 (1 异或 0) 或者 (0 异或 1) 结果才为 1,其他结果都为 0 。只要两个位不相同,那么结果就是 1 。因此问题变成了如何判断两个位不一样。
运算要求两个位都是 1 时,结果才是 1,所以 1 & ~0 结果是 1 而 ~0 & 1 结果也是 1,这作实现了两个位不一样,而结果是 1 。因为存在 1 & ~0~0 & 1,所以异或运算可被拆分为 (1 & ~0) | (~0 & 1) 。推广成 (x & ~y) | (~x & y)lua

通过分析后,发现彻底能够代入上面的函数。因而实现异或的代码以下。操作系统

local function exor(x, y)
	return bis(bic(x, y), bic(y, x))
end

完整的测试用例 Lua 代码以下。code

local function bis(x, mask)
	return x | mask
end

local function bic(x, mask)
	return x & ~mask
end

local function exor(x, y)
	return bis(bic(x, y), bic(y, x))
end

local x, y = 0x12345678, 0x87654321
assert(exor(x, y) == x ~ y

参考内容io

  • 深刻理解计算机操做系统 - 习题 2.13