Day-3 小学数学(bit ver.)

小学数学(bit ver.)

tags: IT铁人

例题答案

不知道各位有没有试试看前面的题目呢??这边稍微讲解一下ㄅ
首先是a.

op=0 (代表R-type), funct=32 (也就是100000)

代表加法ADD指令

rs=1, rt=2, rd=3

分别代表$at, $v0, $v1

所以代表将$at+$v0的结果放在$v1
Assembly的写法就会是

add $v1, $at, $v0

再来是b.

op=43 (101011)

代表sw指令

rs=16, rt=5

分别代表$s0, $a1

而immediate只是代表位移的数量而已

所以代表将$s0中存的位置加上4
结果所指到的位址中的资料放进$a1中
Assembly的写法为

sw $a1, 4($s0)

你答对了吗??

稍微有点困难啦,毕竟sw上次没有提到。
不过大学就是这样嘛,东西很多教授不可能全部讲一次。

所以我们继续努力吧!

二进位转换方式

前面我们在标记register的位置时,使用2进位制,也就是说最初的代表2的0次方,在往前为2的1次方,以此类推,所以当我们要将数字从10进位制转换成2进位制时,基本上用短除法就能够做出来,或是一直用小於当下数字且最大的2的次方减下去也可以,以109来举例的话…

109 - 64 = 45 (1xxxxxx)
45 - 32 = 13 (11xxxxx)
13 < 16 (110xxxx)
13 - 8 = 5 (1101xxx)
5 - 4 = 1 (11011xx)
1 < 2 (110110x)
1 - 1 = 0 (1101101)

当啷!是不是很简单阿~结果就是1101101喔!

负数表示方式

那麽既然正数可以如此表示,那麽负数呢?
既然负数会有一个减号在前面,我们可以在2进位的最前面多增加一个代表正负数的bit。
这就叫做sign and magnitude
所以 109 = 01101101
如果-109 = 11101101
那麽问题来了,以8个bit来表示数字的话
0就有正负0两种可能
+0 = 00000000
-0 = 10000000

另外一种没什麽在用的方法称为1's Complement
就是直接取补数就好(1变0,0变1)
所以 109 = 01101101
那麽-109 = 10010010
这麽一来有些加减法可以正常运作,有些不行
不过0一样有正负0两种表示方法,所以

最後一个最实用的,升级版的前者:2's Complement
取完补数後将结果+1
这麽一来
0 = 00000000
-0 = 11111111 + 1 = 1 00000000
最前面的1会跑出我们在意的8 bit
所以结果仍然是00000000
并且负数换成正数也是同样的作法
有兴趣的同学可以试试看
采用了2's Complement,可以解决正负0的问题 不会撞号

加减法

定义好数字的正负如何表示之後,加减法的部份就简单多了。
加法只要将两者加起来;减法则要将後者变号,再使用加法即可。

举例来说

7 + 9 = 16
00000111
+ 00001001
= 00010000
13 - 20 = -7
00001101
+ 11101100 (00010100的负数)
= 11111001 (00000111的负数)

要特别注意的是,在7+9=16之中,发生了进位,要是进位的时候压到了最前面的bit,就会让人认为结果是负数,这种情况称为Overflow

Overflow

写过程序的同学,应该听过这个词,中文称为溢位(腋味)。
![](https://i.imgur.com/REO8ZFr.jpg =30%x30%)

如果在c语言中执行以下程序码片段

int x = 1000000000;
int y = 2000000000;
printf("%d\n", x+y);

则会出现

-1294967296

这就是因为加法之後进位压到了sign bit,导致程序以为结果为负数。
所以做计算的时候要特别注意,基本上正数加上正数,以及负数加上负数都有可能发生溢位。

加法器

以int来说,最大的数字为 ${2}^{31}-1$,也就是说如果要一次加起两个数字,我们需要一个32 bit的加法器,不过太大了,并且如果又要支援更大的加法,又会需要更大的加法器来一次实施,所以我们不是这样想的,我们用的是多个加法器连接来计算。

也就是说,以一个32 bit的加法来看,我们用的是32个1 bit的加法器,一个一个的加上去,并且将进位往後传,就像是国小老师教的那样,那个我们单纯将一堆加法器连接在一起,就称为Ripple Carry Adder
![](https://i.imgur.com/E40bA13.png =70%x70%)

不过这代表每次都要等前面一个adder做完运算才能轮到下一位。

为了加快速度,出现了新的加法加速器,这就是Carry Lookahead Adder(CLA)

透过逻辑运算,我们可以将前面是否会进位提早告诉後面的adder,这麽一来就能将结果加速,至於CLA的原理,碍於篇幅的关系,杰哥打算留到下一篇再跟各位介绍。

牛刀小试

这篇轻轻松松,我们做两个简单的加减法就好了,题目如下:

a. 28 + 90
b. 30 - 120

在纸上写出计算过程吧~~

上一篇 下一篇
我也...可以跟电脑娘说话吗 CLA以及bit乘法

成为资工金牌之路有你有我


<<:  Day3 简易调色盘小实作

>>:  【Day4】[资料结构]-链结串列Linked List-实作

SQL Server 每日定期备份与定期删除旧有备份档

SQL Server 资料库备份是将存放在资料库里面的资料,转成单一档案保存,通常是副档名为 bak...

Day 16 建立资料库

我们现在有了基本的日志,但是每次输入完重整页面都会刷新,因为这些资料都只存在於浏览器,没有真正储存到...

[Day 5] SRE - 发动测试左移之术,预视未来的机制

测试左移(Shift Left Testing ) 如何事件左移 事先演练未来排定作业 因为团队会在...

开发 App 必备的 4 个免费服务

开发这个 App 至今,已经帮我带来千万以上的收益,但是还是有很多我们常用的服务跟工具,居然到现在都...

D-26.Block、Proc、lambda && Valid Perfect Square

Block说:我让Ruby发光发亮。 Ruby中少数天生不属於物件的存在。 未物件化前,只能依附在有...