登 录
注 册
< 系统运维
Linux
计算机系统
系统工具
系统硬件组成
高速缓存
存储器及操作系统
Amdahl定理
信息表示和处理
内存有关错误
全球IP因特网
信号量同步线程
热门推荐>>>
中台架构
中台建设与架构
Hadoop
源码分析-NN启动(三)
HBase
HBased对接Hive
Linux
Nginx高可用
Python
数据导出工具
Flink
3分钟搭建Flink SQL测试环境
Kafka
Kafka对接Flume
深度学习
卷积神经网络
数据结构与算法
选择合适的算法
MySQL
数据备份恢复
Hive
Hive调优参数大全
其他框架
Azkaban Flow1.0与2.0
ClickHouse
表引擎-其他类型
技术成长
最好的职业建议
精选书单
技术成长书单—机器学习
技术资讯
数据在线:计算将成为公共服务
开发工具
IntelliJ IDEA 20年发展回顾(二)
系统工具
Mac命令行工具
虚拟化
内存虚拟化概述
云原生
云原生构建现代化应用
云服务
一文搞懂公有云、私有云...
Java
Spring Boot依赖注入与Runners
Go
Go函数与方法
SQL
SQL模板
安全常识
一文读懂SSO
当前位置:
首页
>>
计算机系统
>>
信息表示和处理
信息表示和处理
2020-07-05 13:39:48 星期日 阅读:1411
![](/static/images/article_images/1693727784.8007948.jpeg) 现代计算机存储和处理的信息以二值信号表示,这些微不足道的二进制数字,或者称为位(bit),形成了数字革命的基础。 二值信号能够很容易的被表示,存储和传输。孤立的讲,单个的位不是非常有用,然而,当把位组合在一起,再加上某种解释,即赋予不同的可能位模式以含义,我们就能表示任何有限集合的元素。 ####信息存储 大多数计算机使用8位的块,或者字节(byte),作为最小的可寻址的内存单位,而不是访问内存中单独的位。机器级程序将内存视为一个非常大的字节数组,称为虚拟内存(virtual memory)。每个程序对象可以简单的视为一个字节块,而程序本身就是一个字节序列。 #####十六进制表示法 一个字节由8个位组成,在二进制表示法中,一个字节的值域是0000 0000 ~ 1111 1111 。如果看成十进制整数,一个字节的值域为0~255。两种符号表示法对于描述位模式来说都不是非常方便:二进制表示法过于冗长,而十进制表示法与位模式的相互转化很麻烦。替代的方法是,以十六进制表示位模式。 在C语言中,以0x或0X开头的数字常量被认为是十六进制的值。字符A~F可以是大写,也可以是小写。例如我们可以将数字FA1D37B写作0xFA1D37B或者0xfald37b,甚至是大小写混合。 编写机器级程序的一个常见任务就是在位模式的十进制、二进制和十六进制表示之间人工切换。二进制和十六进制之间的转换比较简单直接。一个简单的窍门是记住十六进制数字A、C和F相应的十进制值。而对于把十六进制值B、D和E转换成十进制值,则可以通过计算他们与前三个值的对应关系来完成。 ####字数据大小 每台计算机都有一个子长(word size),指明指针数据的标称大小(norminal size),因为虚拟地址是以这样的一个字来编码的,所以字长决定的最重要的系统参数就是虚拟地址空间的最大大小。也就是说对于一个字长为w位的机器而言,虚拟地址的范围为0~2^w-1,程序最多访问2^w个字节。 最近这些年,出现了大规模的从32位字长机器到64位字长机器的迁移,32位字长限制虚拟地址空间为4千兆字节(4GB),而64位字长使得虚拟地址空间为16EB,大多数64位机器也可以运行为32位机器编译的程序,这是一种向后兼容。 程序员应该力图使他们的程序在不同的机器和编译器上可移植。可移植性的一个方面就是使程序对不同数据类型的确切大小不敏感。比如,许多程序员假设一个声明为int类型的程序对象能被用来存储一个指针。这在大多数32位的机器上能正常工作,但是在一台64位的机器上却会导致问题。 ####寻址和字节顺序 对于跨越多字节的程序对象,我们必须建立两个规则: 这个对象的地址是什么? 在内存中,如何排列这些字节? 在几乎所有的机器上,多字节对象都被存储为连续的字节序列。对象的地址为所使用字节中最小的地址。 例如:假设一个类型为int的变量x的地址为0x100,也就是说,地址表达式&x的值为0x100,那么x的4个字节将被存储在0x100,0x101,0x102,0x103位置。 排列表示一个对象的字节有两个通用的规则,具体列子如下,比如一个w位(比特)的整数,如果按照极小端法在内存中排列的话,存储顺序为:0、1、2、3、4... ... w-5、w-4、w-3、w-2、w-1。 其中0是最低位,而w-1是最高位。 而如果按照极大端法在内存中存储的顺序刚好相反(最高有效字节在最前面) 对于大多数应用程序员来说,其机器使用的字节顺序是完全不可见的。无论为那种类型的机器所编译的程序都会得到相同的结果。不过有时候,字节顺序会成为问题,首先是在不同类型的机器间通过网络传送二进制数据时,一个常见的问题就是当小端法机器产生的数据被发送到大端法机器或者反过来时,接收程序会发现字里的字节成立反序的。为了避免这类问题,网络应用程序的代码编写必须遵守已建立的关于字节顺序的规则,以确保发送方机器将它内的内部表示转换成网络标准,而接收方机器则将网络标准换为它的内部表示。 上述这段话举个现实生活中的列子: A派出所定期会把来访的市民提交的业务送到B派出所办理。B派出所只支持居住证办理,但是来访A派出所的人有的提供的是居住证,有的提供的是身份证,所以,对于A派出所而言,需要把市民提交的身份证转化为居住证后才能移交到B派出所。所以居住证就成了上面讲的网络标准。 ####表示字符串 C语言中字符串编码为一个以nul(其值为0)字符结尾的字符数组。每个字符都由某个标准编码来表示。最常见的是ASCII字符码。 ####表示代码 不同的机器类型使用不同的且不兼容的指令和编码方式,即使是完全一样的进程,运行在不同的操作系统上也会有不同的编码规则,因此二进制代码是不兼容的,二进制代码很少能在不同机器和操作系统组合间移植。 计算机系统的一个基本概念就是,从机器的角度看,程序仅仅只是字节序列,机器没有关于原始源程序的任何信息,除了可能有些用来帮助调试的辅助表以外。 ####关于有符号数与无符号数的建议 就像我们看到的那样,有符号数和无符号数的隐式强制类型转换导致了某些非直观的行为,而这些非直观的特性经常导致程序错误,并且这种包含隐式强制类型转换的细微差别的错误很难被发现。因为这种强制类型转换是在代码中没有明确指示的情况下发生的。程序员经常忽略了它。下面的代码说明里某些由于隐式强制类型转换和无符号数据类型造成的细微错误: ``` float sum_elements(float a[], unsigned length){ int i ; float result =0 ; for (i = 0;i <= length -1 ; i++) result += a[i]; return result ; } ``` 避免这类错误的一种方法就是绝不使用无符号数,实际上除了C以外很少有语言支持无符号整数,很明显。这些语言的设计者认为他们带来的麻烦要比益处多得多。比如,Java只支持有符号整数,并且要求以补码运算来实现。 当我们要把字仅仅看作是位的集合而没有任何数字是意义时,无符号数值是非常有用的。例如:往一个字中放入描述各种布尔条件的标记(flag)时,就是这样。地址自然地就是无符号的,所以系统程序员发现无符号类型是很有帮助的,当实现模运算和多精度运算的数据包时,数字是有字的数组来表示的,无符号值也会非常有用。