关于c++:现代计算机数字表示

45次阅读

共计 2509 个字符,预计需要花费 7 分钟才能阅读完成。

古代计算机数字示意

1 概述

古代计算机存储和解决信息以 二值信号 示意。二值信号能够很容易的被示意、存储和传输,例如能够示意为导线上的高电压、低电压。对二值信号进行存储和执行计算的电子电路非常简单牢靠,制造商能够在一个独自的硅片上集成数百万甚至数十亿个这样的电路。

对于数字而言,有三种比拟重要的示意:

  1. 无符号 (unsigned) 编码:对大于等于零的整数进行编码
  2. 补码 (two's-complement) 编码:对有符号的整数进行编码,蕴含正负数
  3. 浮点数 (floating-point) 编码:对实数进行编码表示,应用以 2 为基准的迷信记数法形式

计算机的示意是应用无限数量的位来对一个数字进行编码,因而,当数字太大以至于不能示意时,运算后果就会溢出(overflow)。

值得注意的是,整数的编码和浮点数的编码解决数字示意有限性的形式不一样:

  • 浮点数编码能够对一个较大范畴的值域进行编码,然而这种示意只是近似的,存在精度缺失
  • 整数编码尽管只能编码一个范畴较小的值域,然而是准确的示意,无效范畴内不会存在精度缺失问题。

2 信息存储

信息在计算机的内存中,往往都是以二进制补码模式存在。对于如何在内存中不便的应用信息,须要两个规定:

  1. 信息的地址是什么?
  2. 如何对信息的字节进行排列?

对于被存储为间断字节的信息对象,对象的地址为所应用字节中最小的地址。

2.1 字节程序

排列一个信息的字节有两个通用的规定:

  • 大端法(big endian):信息的高无效字节寄存在高地址,地无效字节寄存在地址
  • 小端法(litter endian):信息的地无效字节寄存在高地址,高无效字节寄存在低地址

例如,存在一个整型变量 int x = n,它的十六进制示意为0x12345678。那么内存会给它调配四个字节的存储空间。假如地址值为0x100-0x103。那么就0x100 就是低地址,0x103就是高地址。

对于字节的最高无效字节和最低无效字节的程序,是从左往右顺次升高的。12为最高无效字节,顺次类推,78就是最低无效字节。

对于大多数 Intel 兼容机,都是采纳小端模式;IBMOracle 大多数机器则是大端模式;对于挪动端来说,无论是 Andriod 还是 IOS 都是小端模式。

2.2 字符与字符串的示意
2.2.1 字符示意

C或者 C++ 中,对字符采纳某种规范编码进行示意,比拟罕用的有 ASCII 字符码,就是应用 1 个字节的 bit 位来对字符进行编码。

遗憾的是 ASCII 编码仅仅实用于英文文档,对于一些特殊字符以及中文编码不反对。所以 Unicode 联合会整顿订正了反对宽泛语言编码的根本编码 -Unicode 对立字符集,应用 32 位来示意字符。

2.2.2 字符串的示意

C 或者 C++ 中,字符串被编码为一个以 NULL('\0',值为 0) 结尾的字符数组。每个字符由规范编码表示。

2.3 整数示意

整数用 bit 位来示意也有两种不同的形式。一种是只能示意非负整数;另外一种是可能示意负整数、零以及正整数。无论哪种形式,在 内存中 都是以 补码 模式存在。

2.3.1 无符号整数编码

无符号数总是大于等于零,所以无符号数的补码就是它二进制原码自身:

unsigned int num = 10;
// 原码 int 类型占用 32bit
0000 0000 0000 0000 0000 0000 0000 1010
// 补码 内存中寄存的是补码
0000 0000 0000 0000 0000 0000 0000 1010

无符号整数的所有 bit 位都是数字无效位。

2.3.2 有符号整数编码

对于有符号的整数,将其转换为二进制之后,最高位 (最右边)bit 位代表 符号位 ,不参加数据表示。其中0 示意 负数 1 示意 正数

对于补码:

  • 负数补码 = 负数二进制原码
  • 正数补码 = 正数二进制原码除了符号位,其余位取反 + 1
// 无符号整数 负数
int a = 3;
// 3 的原码。第一位是符号位,3 是负数,所以是 0
0000 0000 0000 0000 0000 0000 0000 0011
// 3 的补码
0000 0000 0000 0000 0000 0000 0000 0011
 
// 无符号整数 符数
int a = -3;
// - 3 的原码 第一位符号位,3 是正数 所以是 1
1000 0000 0000 0000 0000 0000 0000 0011
// 而后是反码,除了符号位,其余位取反
1111 1111 1111 1111 1111 1111 1111 1100
// 最初是补码:反码 + 1,这就是负 3 在内存中的模式
1111 1111 1111 1111 1111 1111 1111 1101
2.4 实数示意

在计算机中,实数示意办法与整数的示意办法是不同的。

实数的二进制组成有三个局部符号位、阶码位和尾数位。毋庸置疑,最高无效位是符号位。次高无效位之后是阶码位,它的长度取决于精度范畴,单精度浮点型的精度只有 8 位;双精度浮点型有 11 位阶码位。阶码位之后,残余的就是尾数了。

例如,存在一个单精度浮点型数据 9.65,将其转换为在内存中的二进制示意。其中float 占用 4 个字节。也就是 32 位。所以(以下程序是从右往左):

  • 符号位:占用 1 位,第 31
  • 阶码:次高无效位开始,占用 8 位。第 23~30
  • 尾数:阶码完结之后就是尾数,占用 23 位,第 0~22 位。

上面开始转换:

  1. 9.65 是负数,所以符号位是 0
  2. 确定阶码,首先将 9.65 转为二进制示意:(1001.1010 0110 0110 0110 0110)b;再转为二进制指数示意模式:(1.0011010 0110 0110 0110 0110 * 103)b;阶码 = 指数局部 +127,阶码 = 3 + 127 = 130,应用八位二进制数示意(1000 0010)b
  3. 取步骤 2 中,转为二进制指数模式之后的小数局部作为尾数 001 1010 0110 0110 0110 0110,有余23 位的,低位应用 0 补充

所以,残缺的数据为:(0 1000 0010 001 1010 0110 0110 0110 0110)b。这样组合只是为了分明的看到各局部之间组成。

从新依照 4 个二进制一组(0100 0001 0001 1010 0110 0110 0110 0110)b,应用十六进制示意:(41 1A 66 66)hex

如过应用工具查看内存的话,大端法就是(41 1A 66 66),小端法令是:(66 66 1A 41)

少数电脑都是小端法。,上面就是再小端法示意的电脑上运行后果。

正文完
 0