有符号数的加减乘除

 

加减乘除符号

首先用4位来解释,32位太长,不好解释,四位有符号数的范围是-8~7,无符号数是0~15.

1. 让我们设想一下有符号数的-2 * -2,-2的补码是1110,在无符号数里是14,所以无符号数的乘法相当于14 * 14

二进制乘法

1110

*1110

——-

0000

1110

1110

1110

11000100

4位表示就是0100,补码表示是4,二进制也是4

而有符号-2 * -2 = 4,没有问题, 无符号14 * 14 = 11000100(二进制,这里溢出了),4位截取高位=0100=4

  1. 让我们设想一下有符号数的-2 * 2,-2的补码是1110,2的补码是0010,在无符号数里是14,所以无符号数的乘法相当于14 * 2

    1110

    *0010

    ——-

    11100 

    截取最高位,就是1100,就是-4,而14 * 2溢出,得到的也是1100,就是十进制12.

首先,我们从书上了解到关键的几个知识点:

1. 对无符号和补码乘法,乘法运算的位级表示都是一样的。

2. 机器使用一种乘法指令来进行有符号和无符号整数的乘法,也就是都采用无符号乘法处理,再取低位

按照【谭浩强.C程序设计(第三版).北京:清华大学出版社,2005】的第40页至第41页所述,求一个负数的补码的方法如下:

【例】求-10的补码的方法如下:

1)取-10的绝对值10;

2)10的绝对值的二进制形式为1010;

3)对1010取反得1111 1111 1111 0101(这里假定一个整数占16位)

4)再加1得1111 1111 1111 0110;

即取补码的步骤是将其绝对值按位取反再加1即可……

仍基于上例进行分析,16位存储空间能够存储的有符号型数的范围为-2^16~2^16-1,-10的补码按无符号类型计算其值为65526。

编程时可用如下语句实现:

int i=-10;

i=~abs(i)+1;//abs为取绝对值,~为按位取反

这个语句涉及到了三个操作:一是求绝对值,二是按位取反,三是加1

其实可以用一个加法操作即可搞定……

int i=-10;

i=i+2^16;

可以验证,这种方法是等价的,-10+2^16=65526,在一个有符号型存储变量中存储这个数,相当于存储了一个负数……

其通用的方法是:

变量A用N位来存储,当其为负数时计算其补码的方法是A=A+2^N;

这种方法适用于以下情况但不局限于以下情况:

例如用Matlab产生了一组有符号型数数据,产生这组数据的目的是传给FPGA进行处理,当FPGA的IP核处理有符号数时就是以补码形式进行处理的,这里怎么办呢?

可以这样办:

当matlab产生一组有符号数据后,确定了在FPGA中时使用N位存储处理,则在matlab中再增加一步转换即可:

data_signed=[……];%得到有符号数组

sign=(data_signed<0);%得到与数组对应的符号数组,当数组元素小于0时其值为1,反之为0

data_signed=data_signed+sign.*2^N;%当数组元素小于1时则加上2^N,转化为补码形式

参考:

https://blog.csdn.net/xlhcgd/article/details/48054891

相关阅读

发表评论