加减乘除符号
首先用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
-
让我们设想一下有符号数的-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