Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
think-os-zh
提交
a7f31a47
T
think-os-zh
项目概览
OpenDocCN
/
think-os-zh
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
think-os-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
a7f31a47
编写于
7月 06, 2016
作者:
W
wizardforcel
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ch5.
上级
b47b8d0e
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
88 addition
and
0 deletion
+88
-0
ch5.md
ch5.md
+88
-0
未找到文件。
ch5.md
0 → 100644
浏览文件 @
a7f31a47
# 第五章 更多的位与字节
> 作者:[Allen B. Downey](http://greenteapress.com/wp/)
> 原文:[Chapter 5 More bits and bytes](http://greenteapress.com/thinkos/html/thinkos006.html)
> 译者:[飞龙](https://github.com/)
> 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
## 5.1 整数的表示
你可能知道计算机以二进制表示整数。对于正数,二进制的表示法非常直接。例如,十进制的5表示成二进制是
`0b101`
。
对于负数,对清晰的表示法使用符号位来表明一个数是正数还是负数。但是还有另一种表示法,叫做“补码”(two's complement),它更加普遍,因为它和硬件配合得更好。
为了寻找一个正数的补码,
`-x`
,需要找到
`x`
的二进制表示,将所有位反转,之后加上1。例如,要表示十进制的
`-5`
,要先从十进制的5开始,如果将其写成8位的形式它是
`0b0000 0101`
。将所有位反转并加以会得到
`0b1111 1011`
。
在补码中,最左边的位相当于符号位。正数中它是0,负数中它是1。
为了将8位的数值转换为16位,我们需要对正数添加更多的0,对负数添加更多的1。实际上,我们需要将符号位复制到新的位上,这个过程叫做“符号扩展”。
在C语言中,除非你用
`unsigned`
声明它们,所有整数类型都是有符号的(能够表示正数和负数)。它们之间的差异,以及这个声明如此重要的原因,是无符号整数上的操作不使用符号扩展。
## 5.2 按位运算
学习C语言的人有时会对按位运算
`&`
和
`|`
感到困惑。这些运算符将整数看做位的向量,并且在相应的位上执行逻辑运算。
例如,
`&`
执行“且”运算。如果两个操作数都为1结果为1,否则为0。下面是一个在两个4位数值上执行
`&`
运算的例子:
```
1100
& 1010
----
1000
```
C语言中,这意味着表达式
`12 & 10`
值为8。
与之相似,
`|`
执行“或”运算,如果两个操作数至少一个为1结果为1,否则为0。
```
1100
| 1010
----
1110
```
所以表达式
`12 | 10`
值为14。
最后,
`^`
运算符执行“异或”运算,如果两个操作数其中有一个为1,而不是全部为1,结果为1。
```
1100
^ 1010
----
0110
```
所以表达式
`12 ^ 10`
值为6。
通常,
`&`
用于清除位向量中的一些位,
`|`
用于设置位,
`^`
用于反转位。下面是一些细节:
**清除位:**
对于任何
`x`
,
`x & 0`
值为0,
`x & 1`
值为
`x`
。所以如果你讲一个向量和3做且运算,它只会保留最右边的两位,其余位都置为0。
```
xxxx
& 0011
----
00xx
```
在这个语境中,3叫做“掩码”,因为它选择了一些位,并屏蔽了其余的位。
**设置位:**
与之相似,对于任何
`x`
,
`x | 0`
值为
`x`
,
`x | 1`
值为1。所以如果你将一个向量与3做或运算,它会设置右边两位,其余位不变。
```
xxxx
| 0011
----
xx11
```
**反转位:**
最后,如果你将一个向量与3做异或运算,它会反转右边两位,其余位不变。作为一个练习,看看你能否使用
`^`
计算出12的补码。提示:-1的补码表示是什么?
C语言同时提供了移位运算符,
`<<`
和
`>>`
,它可以将位向左或向右移。向左每移动移位会使数值加倍,所以
`5 << 1`
为10,
`5 << 2`
为20。向右每移动移位会使数值减半(向下取整),所以
`5 >> 1`
为2,
`2 >> 1`
为1。
## 5.3
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录