无符号数
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
无符号数据若干问题
一、总论
计算机中数据表示分两种格式:定点格式、浮点格式。
目前计算机中大多数定点数只用于表示整数数据定点数只用于表示整数数据定点数只用于表示整数数据,,而小数则通过浮点数据表示实现而小数则通过浮点数据表示实现。
在定点数据表示中,若所有的位都表示数值含义,则该数为无符号数据,通常为正数。如用8位表示无符号整数,即0000 0000~1111 1111,表示值为0~255。
若数据表示的最高位代表符号含义,则该数为有符号数据,通常用补码表示。
浮点数一般认为是带符号的。
二、运算
计算机运算电路是按有符号数的补码表示运算规则设计的,在数据运算的时候并不区分操作数是有符号的还是无符号的。如:
1000 0010
+1111 1000
——————
1 0111 1010
如果把这两个数理解为有符号数-126和-8相加,按补码加法规则,进位丢去,得到结果122是错的,因为产生了溢出。
如果把两个操作数理解为无符号数130和248相加,考虑进位,结果为122+256=378,结果正确(不考虑进位,结果也溢出)。
如果把这两个数理解为-126减8,结果溢出。
理解为无符号数130减8,结果122正确不溢出。
三、标志位
计算机的运算器在做完计算之后,设置相应标志位。
最高位产生的进位需结合指令功能设置进位标志,若为加法指令,最高位产生的进位设置为进位标志;若为减法指令,最高位产生的进位取反后设置为进位标志。
计算机中对CF 的置值的置值,,从无符号数运算角度从无符号数运算角度,,有进位置1,无进位置0;有借位置1,
无借位置0。
从电路运算角度从电路运算角度,,当电路最高位向前有进位1时,若执行的是加法指令若执行的是加法指令,,对CF 置1,若执行的是减法指令若执行的是减法指令,,对CF 清0;当电路最高位向前进位0时,若执行的是加法指令若执行的是加法指令,,对CF 清0,若执行的是减法指令若执行的是减法指令,,对CF 置1。
根据最高位和次高位产生的进位的异或设置溢出标志。
通常计算机在做算术运算之后还可能设置另外两个标志,如果计算结果的所有位都是0则设置零标志,如果计算结果的最高位是1则设置负数标志。
至于这个加法到底是有符号数加法还是无符号数加法则取决于程序怎么理解了,如果程序把它理解成有符号数加法,是否溢出就要检查溢出标志,如果程序把它理解成无符号数加法,是否溢出就要检查进位标志。
如果程序把计算结果理解成有符号数,也可以检查负数标志判断结果是正是负;但把结果理解成无符号数,负数标志就没有任何意义了。
如果两数比较大小如果两数比较大小,,计算机中对两数做减操作计算机中对两数做减操作,,实际电路按补码做加运算实际电路按补码做加运算,,无符号数比较大小用CF ,CF=1,低于低于;;CF=0,高于高于。。有符号数比较大小用OF 、SF 配合配合,,若OF=SF ,大于大于;;若OF ≠SF ,小于
汇编中CMP 只做比较只做比较,,有没有符号没有关系有没有符号没有关系,,判断的时候判断的时候才才有符号区分有符号区分。。
无符号比较无符号比较::JA (CF=ZF=0)
、JB (CF=1)、 有符号比较有符号比较::JG (OF=SF 且ZF=0)
、JL (OF ≠SF )、
四、程序中应用
从编程规范上来讲,无符号数不能做小减大的运算,这会导致向下溢出,运算结果是一个巨大的数值(可以对其表示按有符号补码表示理解可以对其表示按有符号补码表示理解可以对其表示按有符号补码表示理解,,得到小减大的负值结果得到小减大的负值结果;;而对巨大的数值也可理解为小数借位后减大数的结果的数值也可理解为小数借位后减大数的结果)。无符号数的减法应先判断再运算,必须是大数减小数。对于编程来说,安全性永远都比效率更重要。
我们平时写程序用高级语言,高级语言的代码被编译器“翻译”成汇编代码,然后再进一步“翻译”成机器代码。CPU 执行的是机器代码,而机器代码几乎就是汇编代码的直接翻译。
在汇编代码中,对于加减法,有符号与无符号是没有任何区别的。
有符号与无符号的区别只在乘除法、向高位扩展、向右移位等地方。
在C 语言中,允许定义unsigned 类型数据。C 中能进行数据的强制类型转换,也具有自动转换原则,当表达式中存在有符号类型和无符号类型时,所有的操作数都自动转换为无符号类型,从这个意义上讲,无符号数的运算优先级要高于有符号数。
如:
Unsigned int a=20;
Signed int b=-130;
a>b ?还是b>a ?实验证明b>a ,这是因为在C 语言操作中,如果遇到无符号数与有符号数之间的操作,编译器会自动转化为无符号数来进行处理,因此a=20,b=4294967166,这样比较下去当然b>a 了。
(C 中的无符号数和有符号数之间转换的原则是基本的位表示保持不变中的无符号数和有符号数之间转换的原则是基本的位表示保持不变)
再如:
Unsigned int a=20;
Signed int b=-130;