计算机中如何实现 5-8?
首先要证明反码和原码之间的关系
原码 000 0101
反码 111 1010
---------------------
111 1111
所以 111 1111
- 000 0101(原码)
-------------------------
111 1010(反码)
我们只要将原码与反码的和加上1,就能变成1000 0000,而1000 0000是byte的模。
然后利用反码和补码之间的关系求出x:
x = 1000 0000 - 减数(原码)
= 111 1111 + 1 - 减数(原码)
= 111 1111- 减数(原码)+1
= 反码 +1
所以在计算中规定了一个补码 x= 补码 = 反码 +1
补码和原码的关系是: 补码 = 模 - 原码
所以 差 = 被减数 + 减数的补码
所以,计算机规定,正整数的反码,补码等于原码;负数的反码为除符号位不变外,每一位数取反(0变1,1变0),补码为 反码 +1。
所以可以得到计算公式: 差 = 被减数的补码 + 减数的补码
为计算方便,当你输入一个负数时,计算机自动会将负数转换成这个负数的补码存储在计算机中,而正数的补码就是原码,所以就有计算机中存储的都是这个数的补码。
所以8 - 5 在计算机中的表达是 0000 1000 (8的补码)
1111 1011( -5的补码)
----------------------------
10000 0011
因为计算机会舍弃超出存储空间的部分,10000 0011 = 0000 0011
符号位为0,是正数,这也解释了为什么设计0代表正数,1代表负数,因为8(000 1000)比5(000 0101大,所以000 1000加上000 0101的补码结果一定会进1,所以最后符号位会变成0,结果位正数。
因为我们求的是补码的和,所以显示结果的时候要将它转化成原码, 0000 0011的符号位是0,正数,正数的补码就是它的补码,所以原码是0000 0011=3(证明过程见后面)。
下面我们要面对另一个问题,如果被减数小于减数怎么办,以5-8为例
根据计算公式 : 差 = 被减数的补码 + 减数的补码
5的二进制位补码是000 0101,-8的二进制补码是1111 1000。
0000 0101
1111 1000
---------------
1111 1101
因为我们求的是补码的和,所以显示结果的时候要将它转化成原码,那怎么转换成原密码呢。
从上面的计算可知: 补码 = 模 - 原码
所以 原码 = 模- 补码
原码=补码 + 补码的反码 + 1-补码
原码 = 补码的反码 + 1
所以可以看出,原码就是对计算结果求补码,所以1111 1101的补码为1000 0011=-3。
1、在verilog中有时会用signed修饰符来修饰定义的数据,运算的时候也会用$signed()任务来强制转换数据,那么signed的修饰是为什么呢,是为了区分有符号数和无符号数的加法和乘法吗?其实不是的,因为有符号数和无符号数据的加法强结果和乘法器结构是一样的,$signed()的真正作用是决定如何对操作数扩位的问题。
2、verilog中的加法和乘法操作前,会先对操作数据扩位成结果相同的位宽,然后进行加法或者乘法处理。比如a/b都为4位数据,c为5位数据,c = a + b,这个运算的时候会先把a和b扩位成5位,然后按照无符号加法进行相加。a/b没有被signed修饰的时候会按照无符号数的扩位方式进行扩位,即高位补0,加法的结果当然也是a、b为无符号数相加的结果。
3、如果想把a、b作为有符号数来相加,那么就得在a/b数据定义的时候用signed修改,或者在计算的时候用$signed()来修饰,这样在c = a + b,这个运算开始的扩位就会按照有符号数的方式进行扩位,在高位补符号位,加法得出的结果就是a、b视为有符号数的结果。当然c要视为有符号数据。
浙公网安备 33010602011771号