谈“complement”

Posted by HX on 2018-06-24 | 👓

complement 这个词以及它的形容词 complementary 和 complete 是同源的。所以 complement 是“使某物完整的东西”/“补充物”的意思,动词“使某物完整”/“补充某物”是后起义。

其实 complement 本身并没有什么有趣的,有趣的是它在各个领域中作为专门术语的意思以及相应的中文翻译。

语法中的补语,就是 complement 的翻译,取的是“使谓语部分完整的东西”的意思。例如 He is mad. 中,mad 是补语,单独的 He is 意思是不完整的,加上补语才完整。He drove her mad. 中,mad 也是补语,或称宾补,单独的 He drove her 意思也是不完整的。(语言学上的补语意思很广,不同的语法流派对补语也有不同定义)

几何上的余角,是 complementary angle 的翻译,取“使另一个角完整的角”的意思,这里的完整就是指 \(90\) 度(当然“完整”的定义各术语不同),一个角加上它的余角就完整了(相加等于 \(90\) 度)。

余弦、余切、余割分别是 cosine, cotangent, cosecant 的翻译,里面的 co- 是 complementary 的缩写,所以一个角的 cosine(余弦值)就是这个角的 complementary angle(余角)的 sine(正弦值)。

计算机科学里的反码,是 ones’ complement 的翻译(也有地方翻译成“一补数”),取“使另一个数完整的数”的意思,这里的完整就是指 n 个 \(1\)(所以叫 ones’ complement, one 是复数表明有多个 \(1\)),n 是原码的位数。换句话说,一个数的 ones’ complement 是使得二者相加等于 n 个 \(1\) 的数。举个例子(下面都是二进制数):

\(10000010\) 的反码是 \(01111101\),因为 \(10000010 + 01111101 = 11111111\).

(对补码不清楚的人就别看这段了,以免混乱)

同样还有补码,是 two’s complement 的翻译(也有地方翻译成“二补数”),也取“使另一个数完整的数”的意思,这里的完整是指 \(2\)(对于小数)或者 \(2^n\)(对于整数),n 是原码的位数,所以叫 two’s complement。换句话说,一个数的 two’s complement 是使得二者相加等于 \(2\) 或者 \(2^n\) 的数。注意,英语里 two’s complement of x 和 two’s complement notation/representation of x 是不一样的,前者是对 x 求补后的数,后者是 x 的补码表示形式,中文里常说的“正数的补码和原码相同”指的是后者,即“正数的补码表示与原码表示相同”。求补运算就是上面说的,用 \(2\)\(2^n\) 减去 x。

为什么偏偏是 \(2^n\) 呢?(从英语科普变成 CS 科普)

\(2^n\) 的二进制形式是 \(1\) 后面跟 n 个 \(0\),比如 \(2^4\,_{(10)}\) = \(10000\,_{(2)}\),这有 \(5\) 位,而原来的数是 \(n=4\) 位,多出来的最高位 \(1\) 会作为溢出扔掉,所以 \(2^n\) 其实会被当成 \(0\)(如果机器数只能存 \(4\) 位的话),这相当于 一个数(用补码表示) + 它自己求补后的数 = \(0\)。所以正数的补码表示是其本身,而负数的补码表示是相应正数求补后的数。例如,\(0001\)\(1\) 的补码表示) + \(1111\)\(-1\) 的补码表示) = \(10000\),扔掉溢出位等于 \(0\). 而原码和反码不具有这样的性质。至于为什么要搞这么多,是因为把减法转换为加法来做,就可以只用加法器同时做加减两种运算,而现在的计算机也的确是这么设计的…(也可以设计减法器但那样加减要用不同元件有开销的问题)

当然我只是从英语的角度来看,我知道有大佬可以从群论或者环论的角度来解释这个补码,向大佬低头orz

就扯这么些吧。