您的位置 首页 数字

计算机中信息的表明与处理

一切又回到了学习、总结、学习、总结模式,回顾了一下找工作期间遇到的很多问题,其实归根到底是因为基础不牢固,没有搞清楚其中的一些本质

全部又回到了学习、总结、学习、总结方法,回忆了一下找工作期间遇到的许多问题,其实归根结底是由于根底不结实,没有搞清楚其间的一些本质。就像前一章总结的浮点型运算相同,关于其他的数据类型都存在各式各样的难点,略微不留意就会导致过错的发生。这些本质的东西本不应该现在来学习,但亡羊补牢为时不晚。

信息的编码方法
核算机中信息都是以0、1两种数据来表明的,咱们都知道,可是便是这两个简略的0、1怎么完结了核算机的强壮核算呢?这就触及到了核算机中信息的表达和处理。在大学核算根底课上,开端就触及了二进制、八进制、十进制、十六进制等进制之间的转化方法。其间二进制是核算机的完结方法,其他的进制都是出于一些意图界说的。在二进制中有三个根底概念:原码、反码、补码是十分重要的,许多人也对三者之间的转化方法十分清楚。
原码:关于十进制的数据,能够选用多个0、1构成的比特向量表明,其间最高位表明符号位,当为1时,表明这个数为负数,当为0时,表明这个数为正数。
反码:是指原码符号位在外的其他位进行取反操作,可是取反操作只针对负数,也便是说正数的原码等于反码。
补码:也仅仅针对负数而言,关于负数补码是指在反码的根底上加1即表明补码(可是不能改动符号位数据)。关于正数而言,补码等于反码,等于原码。
咱们能够这样以为,为了处理负数的问题,在核算机中引入了反码、补码的概念,且补码、反码首要针对的目标便是负数,正数的补码、原码、反码是相同的bit向量。

在实践运用中补码比较别的两种编码方法愈加的便利,因而关于有符号整形类型,简直一切的编译器中都是选用补码方法进行编码,了解到编译器是选用补码的方法存储核算机的整形数据信息是十分重要的。

一般来说,关于有符号的整数型数据类型,即char、short、int这品种数据类型,都是选用补码方法编码的,可是关于无符号的整数型数据类型,一般都是选用原码的方法编码的,也便是单纯的比特向量,没有符号位之说,由于常用的核算机体系都是32bit,这也是为什么说核算机的地址空间是4G=2^32字节。char型数据类型占1字节的空间,而short类型一般占用2字节的空间,int型数据占用4个字节的空间。32个bit刚好占有4字节,因而咱们能够以为int数据实践上便是一个32个bit向量。

由实践状况可知:
int型的规模是-2^31—2^31-1,能够以为对错对称的空间。无符号的unsigned int的规模则是0到2^32-1之间。
char型的规模是-128到-127之间,unsigned char的规模则是0到255之间,在许多的使用中能够充分运用char的规模减小存储量。
short的规模是-2^15到2^15-1,unsigned short 的规模是0-2^16-1。
需求了解的是有符号的整数型数据都是选用补码方法进行编码的,而无符号的数据类型一般选用原码方法编码(正数)。两种编码方法表明数据的规模存在不同,实践上在C言语编程的进程中都会进行隐式的强制类型转化,假如不清楚编码方法的不同,就很难精确的掌握核算的不同。在嵌入式编程中常常会有一些简略的推迟操作,假如编写不恰当就会导致过错发生。如下所示:

void delay(int time)
{
unsigned char i = 0;
for(; time >= 0; — time)
for(i = 0; i < 256; ++ i)

}

这个题乍一看没什么问题,可是细心琢磨就会发现存在问题,由于存在死循环,unsigned char的最大值是255,不或许大于等于256,因而一向满意条件,也便是说第二个循环会一向履行,这便是典型的不留意规模问题。
还有一个典型的排序问题:

unsigned char array[1000][1000];

void sort(unsigned char (*a)[1000])
{}

这种归于典型的大数排序问题,只要挑选适宜的排序战略才干削减排序的时刻杂乱度,那么怎么完结呢?最简略的方法是选用计数排序,时刻杂乱度为O(n)。充分利用了unsigned char的数值规模在0-255之间这个规模。
左移右移处理
在整形数据类型中有一个问题便是典型的移位操作,在机器言语中也会有位操作,在C言语中也存在位操作,这为直接操控CPU供给了较好的完结方法。移位首要包括左移和右移操作,其间左移的完结是在当时数据的bit向量向左移动n个bit,后续的bit补0。
而右移比左移杂乱一些,右移存在两种:逻辑右移和算术右移,逻辑右移首要是针对无符号型数据,逻辑右移是指将当时的bit向量向右移动,左面bits补零。算术右移首要针对有符号型数据,将当时数据右移,左面补上最高bit的值。这种完结方法能够确保数据的符号不改动,也便是说负数经过右移今后仍是负数,不会变成正数。而逻辑右移则不可,负数经过逻辑右移今后就变成了正数,这是不合理的。因而能够总结如下:

关于左移操作,不管是有符号仍是无符号类型,都是右端直接补零。这时分或许导致数据发生较大的改动,正数经过左移变成了负数,呈现这些的原因实践上是左移操作疏忽了进位操作,正负都是合理的。在整形数据中常常选用左移操作完结数据的乘法操作,两个正数相乘是有或许发生负数的。比方:

int x1 = 0x60000000;
printf(“%d,%d,%d”,x1,x1<<1,x1*2);

这段代码就阐明晰两个正数相乘是能够发生一个负数的,可是假如咱们选用无符号数据类型进行左移操作就不会发生两个正数相乘发生负数的状况,这样能够防止许多难以想象的成果。
右移操作中的逻辑右移首要是针对无符号数据类型,对有符号的数据类型是无效的,关于有符号的数据类型,右移操作关于大多数的编译器都以为是算术右移,算术右移能够确保数据的正负特性,不会发生左移中两个正数相乘得到负值的状况。算术右移的本质是在移位操作今后,数据的左面选用符号位填充。通常在C言语中右移完结除法操作,比方8>>1,即完结了除以2的操作,关于无符号型数据能够选用右移操作完结除法操作,可是关于有符号数据类型或许呈现过错。下面说一个典型的比如:

int x1 = -1;
printf(“%d,%d,%d”,x1,x1>>1,x1/2);

这个比如阐明晰有符号数据类型经过算术右移并不能完结除法操作,可是无符号的数据类型根本上能够完结除法操作。搞清楚何时是算术右移何时是逻辑右移是十分有必要的。
关于无符号数据类型,选用左移右移的方法进步乘除法的速度是可行的,可是对有符号的数据类型最好不要选用这种完结方法,由于或许会呈现意想不到的成果。尽管许多的程序书中主张少用unsigned的类型,可是在移位操作这方面最好仍是处理无符号型目标比较有确保。

强制类型转化处理
强制类型转化是C言语中比较重要的一个主题,其间程序员内行也会疏忽这种问题的发生,根本的完结方法是有符号向无符号改动,小字节数据朝大字节数据转化,当然也有高字节数据类型往低字节数据改动的问题。
根本的转化存在两种:零扩展和符号扩展。
零扩展是针对无符号数据类型,将一个小字节数据转化为大字节数据时,在高字节中填充零,完结数据的共同型。
符号扩展则针对有符号数据类型,将一个小字节数据转化为大字节数据时,在高字节中填充小字节数据的符号位,填充符号位首要是为了完结补码共同准则。零扩展实践上是符号扩展的子类。
大字节数据向小字节数据转化的进程是一个截取进程,这样或许会导致数据正负的改动,也便是说大到小的进程或许发现比较大的改动,截取数据的一部分作为小字节数据的bit向量。
强制类型转化本质上包括了符号扩展,和零扩展,符号扩展确保了补码的共同型,零扩展则确保了数值巨细的共同性,符号扩展针对有符号数据类型,而零扩展首要针对无符号数据类型。
许多时分的强制类型转化是隐含进行的,这是就需求咱们精确的掌握,有符号类型到无符号类型的改动会导致很大的不同,由于无符号类型数加上有符号类型数将进行有符号到无符号数据类型的转化,这时分就会发生一个无符号的数据,不会发生有符号类型的数。
一起还有一个技巧,在C言语中怎么判别两个数的和是否越界的问题,由于许多编译器对越界并不报错,这时分能够经过判别两个数的和是否小于任何一个数即可,假如小于任何一个,则阐明这个数便是越界,不然没有发生越界问题。
详细的完结能够选用下面的代码测验:

int test()
{
char x2 = -20;
int x1 = x2;
printf(“x2 = %d, x1 = %u”,x2,x1);
x2 = 20;
x1 = x2;
printf(“x2 = %d, x1 = %u”,x2,x1);
}

浮点型数据类型
浮点型数据类型在前一章中现已阐明晰,浮点型数据类型没有无符号和有符号之说。浮点型具有固定的编码方法,原本便是存在正负之分,即没有unsigned float之说。需求留意的是浮点型是一个近似的值不能用来比较。还有对float类型数据不能进行移位操作,由于float是有固定的编码方法的不像整形数据。

总结
了解核算机中的有符号整型数据一般依照补码的方法存在,有符号数据类型的扩展是依照符号扩展,而不是简略的零扩展,符号扩展是零扩展的延伸,首要是确保在延伸的进程中符号、数值坚持不变。
在移位操作进程中,有符号、无符号数据类型的左移都没有问题,可是或许会导致数据类型的改动,特别是有符号数据类型。关于关于右移操作需求留意,有符号数据类型是算术右移,而无符号数据类型是逻辑右移,右移的不同是在左端补齐的值的不同。
在用移位来模仿数据的乘除法时特别要留意,对无符号数据类型是最有用的,左移右移的值也是咱们以为正确的值,可是假如是对有符号数据类型进行右移模仿除法进程,左移模仿乘法进程时或许导致成果不是所想。因而主张只对无符号数据类型选用移位来简化乘除操作。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/zhishi/shuzi/317751.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部