关于有符号数、无符号数和数据类型的总结.docx_第1页
关于有符号数、无符号数和数据类型的总结.docx_第2页
关于有符号数、无符号数和数据类型的总结.docx_第3页
关于有符号数、无符号数和数据类型的总结.docx_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一、 CPU只会根据输入信号进行逻辑运算,在硬件级别是没有有符号无符号的概念,运算结束会根据运算前的信号和输出信号来设置一些标志位,是不是有符号由写程 序的人决定,标志位要看你把操作数当有符号还是无符号来选择,就像内存中的数据,你可以按照需要来解析,原始数据在那里,你要按什么数据格式来解析在于自 己的选择,所以玩汇编的要做到心里有数,加减法只有一套指令,因为这一套指令同时适用于有符号和无符号。下面这些指令:mul div movzx 是处理无符号数的,而这些:imul idiv movsx 是处理有符号的。举例来说:内存里有 一个字节x 为:0x EC ,一个字节 y 为:0x 02 。当把x,y当作有符号数来看时,x = -20 ,y = +2 。当作无符号数看时,x = 236 ,y = 2 。下面进行加运算,用 add 指令,得到的结果为:0x EE ,那么这个 0x EE 当作有符号数就是:-18 ,无符号数就是 238 。所以,add 一个指令可以适用有符号和无符号两种情况。(呵呵,其实为什么要补码啊,就是为了这个呗,:-))乘法运算就不行了,必须用两套指令,有符号的情况下用imul 得到的结果是:0x FF D8 就是 -40 。无符号的情况下用 mul ,得到:0x 01 D8 就是 472 。二、C又是可怕的,因为它把机器层面的所有的东西都反应了出来,像这个有没有符号的问题就是一例(java就不存在这个问题,因为它被设计成所有的整数都是有符号的)。为了说明c的可怕特举一例:#include #include int main() int x = 2; char * str = abcd; int y = (x - strlen(str) ) / 2; printf(%dn,y);结果应该是 -1 但是却得到:2147483647 。为什么?因为strlen的返回值,类型是size_t,也就是unsigned int ,与 int 混合计算时类型被自动转换了,结果自然出乎意料。观察编译后的代码,除法指令为 div ,意味无符号除法,即将-2看做无符号数了。解决办法就是强制转换,变成 int y = (int)(x - strlen(str) ) / 2; 强制向有符号方向转换(编译器默认正好相反),这样一来,除法指令编译成 idiv 了。我们知道,就是同样状态的两个内存单位,用有符号处理指令 imul ,idiv 等得到的结果,与用无符号处理指令mul,div等得到的结果,是截然不同的!所以牵扯到有符号无符号计算的问题,特别是存在讨厌的自动转换时,要倍加小心!(这里自动转换时,无论gcc还是cl都不提示!)为了避免这些错误,建议,凡是在运算的时候,确保你的变量都是 signed 的。三、自动类型转化时的,短字节向长字节转化时,有符号数会符号扩展,无符号数会0扩展;长字节向短字节转化时,会自动截取高位,留下低位字节。特别在做算术运算时,比如乘除法,就可能涉及到有符号数自动转化为无符号数,从而采用不同的指令处理。例如:下面的代码输出是什么,为什么?void foo(void)unsigned int a = 6;int b = -20;(a+b 6) ? puts( 6) : puts(6”。原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数,所以该表达式 计算出的结果大于6。这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。如果你答错了这个问题,你也就到了得不到这份工作的边缘。扩展一下,如果是这段代码呢?void foo(void)unsigned int a = 6;int b = -20;printf(%dn,a+b);(a+b 6) ? puts( 6) : puts(6 为什么?我们要注意,在printf()中,a+b也是转换为unsigned int(0xF2)的,但是%d要求又是按照有符号数输出,所以0xf2当成有符号数输出了-14。四。特别注意在有常数的算数表达式中,往往有隐含的数据类型转化,因为整数常量并没有明确的被指出其的数据类型,整常数在不加特别说明时总是正值。如果需要的是负值,则负号“-”必须放置于常数表达式的前面。每个常数依其值要给出一种类型。当整常数应用于一表达式时,或出现有负号时,常数类型自动执行相应的转换,十进制常数可等价于带符号的整型或长整型,这取决于所需的常数的尺寸。八进制和十六进制常数可对应整型、无符号整型、长整型或无符号长整型,具体类型也取决于常数的大小。如果常数可用整型表示,则使用整型。如果常数值大于一 个整型所能表示的最大值,但又小于整型位数所能表示的最大数,则使用无符号整型。同理,如果一个常数比无符号整型所表示的值还大,则它为长整型。如果需 要,当然也可用无符号长整型。但是,可以在一个常数后面加一个字母l或L强制其数据类型,则认为是长整型。如1 0 L、7 9 L、0 1 2 L、0 11 5 L、0 X A L、0 x 4 f L等。L, U, LU,叫类型后缀,. 一般在程序中出现3种数据.我把它们叫,变量,常量,字面量.变量,常量一般都已经规定了类型了的,所以后缀针对

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论