计算机系统基础知识_数据表示方式

本文详细介绍了计算机中机器数的各种表示方法,包括原码、反码、补码及移码的概念与特点,以及定点数和浮点数的具体表示方式。特别针对IEEE754浮点数标准进行了深入解析,涵盖了单精度、双精度和扩充精度浮点数的格式与运算规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

计算机中不管是任何形式的数据最终都表示为二进制数,也即只有0和1组成的数,又称为机器数。

为了便于表示和计算各类型的数值,又约定了有如有符号数、无符号数、各种码制等。

一般而言,机器数分为有符号数和无符号数。

有符号数,最高位表示的是正/负,其他位用于表示数值无符号数仅表示正数。它们又有两种约定,一种是表示纯小数,另一种是表示纯整数,前者约定小数点位于最高位之前,后者约定小数点位于最高位之后,但计算机中并不真正的保存小数点,都是人为约定的

而对于含小数的整数,则使用定点数浮点数来表示。

本文的介绍将假定你具备二进制与十进制的转换及其运算规则,如果对进制转换不熟悉可以去看该文:数各进制间的转换

机器数的表示

对于无符号数而言,运算相对简单,但有符号数则有点不同,为了便于运算实现,有符号数又可以采用原码、反码、补码和移码等不同码制的编码方式。有符号数最高位仅表示正负,一般地 0表示正,1表示负。 下面假定机器字长表示为n,均为8位。

原码

原码表示法,即数值被转换为二进制值的原始值。

若X是纯整数,则其定义:
X 原 = { X   0 ≤ X ≤ 2 n − 1 − 1 2 n − 1 + ∣ X ∣   − ( 2 n − 1 − 1 ) ≤ X ≤ 0 X_原 = \begin {cases} X &\ 0 \leq X \leq 2^{n-1}-1\\ 2^{n-1}+|X| &\ -(2^{n-1}-1)\leq X \leq 0 \end{cases} X={X2n1+X 0X2n11 (2n11)X0
若X是纯小数,则其定义:
X 原 = { X   0 ≤ X &lt; 1 2 0 + ∣ X ∣   − 1 &lt; X ≤ 0 X_原 = \begin {cases} X &amp;\ 0 \leq X &lt; 1\\ 2^0+|X| &amp;\ -1 &lt; X \leq 0 \end{cases} X={X20+X 0X<1 1<X0
下面是一些示例(其中小数点就是约定小数点的位置):
+ 1 原 = 0 0000001 − 1 原 = 1 0000000 + 12 7 原 = 0 1111111 − 12 7 原 = 1 1111111 + 2 8 原 = 0 0011100 − 2 8 原 = 1 0011100 + 0. 5 原 = 0 . 1000000 − 0. 5 原 = 1 . 1000000 +1_原 = 0 \quad 0000001 \quad\quad\quad\quad -1_原 = 1 \quad 0000000 \\ +127_原 = 0 \quad 1111111 \quad\quad\quad\quad -127_原 = 1 \quad 1111111 \\ +28_原 = 0 \quad 0011100 \quad\quad\quad\quad -28_原 = 1 \quad 0011100 \\ +0.5_原 = 0 \quad.1000000 \quad\quad\quad\quad -0.5_原 = 1 \quad .1000000 +1=000000011=10000000+127=01111111127=11111111+28=0001110028=10011100+0.5=0.10000000.5=1.1000000

反码

反码十分简单,它既是在原码不改变符号位的基础上,对原码的正数不做任何改变,而对负数的每一位取反。

下面是一些示例:
+ 1 反 = 0 0000001 − 1 反 = 1 1111110 + 12 7 反 = 0 1111111 − 12 7 反 = 1 0000000 + 2 8 反 = 0 0011100 − 2 8 反 = 1 1100011 + 0. 5 反 = 0 . 1000000 − 0. 5 反 = 1 . 0111111 +1_反 = 0 \quad 0000001 \quad\quad\quad\quad -1_反 = 1 \quad 1111110 \\ +127_反 = 0 \quad 1111111 \quad\quad\quad\quad -127_反 = 1 \quad 0000000 \\ +28_反 = 0 \quad 0011100 \quad\quad\quad\quad -28_反 = 1 \quad 1100011 \\ +0.5_反 = 0 \quad.1000000 \quad\quad\quad\quad -0.5_反 = 1 \quad .0111111 +1=000000011=11111110+127=01111111127=10000000+28=0001110028=11100011+0.5=0.10000000.5=1.0111111
一个特殊的情况是,0的反码有两种形式 0 反 = 0000000 = 11111111 0_反=0000000 = 11111111 0=0000000=11111111

补码

补码的正数和反码原码一致,但不同的是,它对负数的表示是在反码的基础上加1。

下面是一些示例:
+ 1 补 = 0 0000001 − 1 补 = 1 1111111 + 12 7 补 = 0 1111111 − 12 7 补 = 1 0000001 + 2 8 补 = 0 0011100 − 2 8 补 = 1 1100100 + 0. 5 补 = 0 . 1000000 − 0. 5 补 = 1 . 1000000 +1_补 = 0 \quad 0000001 \quad\quad\quad\quad -1_补 = 1 \quad 1111111 \\ +127_补 = 0 \quad 1111111 \quad\quad\quad\quad -127_补 = 1 \quad 0000001 \\ +28_补 = 0 \quad 0011100 \quad\quad\quad\quad -28_补 = 1 \quad 1100100 \\ +0.5_补 = 0 \quad.1000000 \quad\quad\quad\quad -0.5_补 = 1 \quad .1000000 +1=000000011=11111111+127=01111111127=10000001+28=0001110028=11100100+0.5=0.10000000.5=1.1000000
这样一来,补码的0就存在唯一的表示值 0 补 = 00000000 0_补=00000000 0=00000000

移码

移码即是在数X的基础上,加一个偏移量来表示,一般是用于浮点数的阶码。它有点特殊,所以看看它的定义,规定偏移量为 2 n − 1 ​ 2^{n-1}​ 2n1

若X是纯整数则其定义:
X 移 = 2 n − 1 + X − 2 n − 1 ≤ X &lt; 2 n − 1 X_移 = 2^{n-1} + X \quad\quad\quad-2^{n-1} \leq X &lt; 2^{n-1} X=2n1+X2n1X<2n1
若X是纯小数则其定义:
X 补 = 1 + X − 1 ≤ X &lt; 1 X_补 = 1 + X \quad\quad\quad\quad -1 \leq X &lt; 1 X=1+X1X<1
下面是一些示例:
+ 1 移 = 1 0000001 − 1 移 = 0 1111111 + 12 7 移 = 1 1111111 − 12 7 移 = 0 0000001 + 2 8 移 = 1 0011100 − 2 8 移 = 0 1100100 + 0 移 = 1 0000000 − 0 移 = 1 0000000 +1_移 = 1 \quad 0000001 \quad\quad\quad\quad -1_移 = 0 \quad 1111111 \\ +127_移 = 1 \quad 1111111 \quad\quad\quad\quad -127_移 = 0 \quad 0000001 \\ +28_移 = 1 \quad 0011100 \quad\quad\quad\quad -28_移 = 0 \quad 1100100 \\ +0_移 = 1 \quad 0000000 \quad\quad\quad\quad -0_移 = 1 \quad 0000000 +1=100000011=01111111+127=11111111127=00000001+28=1001110028=01100100+0=100000000=10000000
在偏移量为 2 n − 1 ​ 2^{n-1}​ 2n1的情况下,其实移码只需要将补码的符号位取反即可。

定点数和浮点数

数在计算机中有两种表现形式,一种是约定小数点的位置不变,称之为定点数,另一种的位置不固定,又叫做浮点数

定点数

小数点位置不变的数就是定点数,前面提到的纯小数或纯整数的表现方式都是定点数,它们都是约定小数点在最高有效数值位之前或最低有效数之后。

如机器字长为n,各种码制下带符号数的表示范围如下:

码制定点整数定点小数
原码 − ( 2 n − 1 − 1 ) -(2^{n-1}-1) (2n11) ~ + ( 2 n − 1 − 1 ) ​ +(2^{n-1}-1)​ +(2n11) − ( 1 − 2 − ( n − 1 ) ) -(1-2^{-(n-1)}) (12(n1)) ~ + ( 1 − 2 − ( n − 1 ) ) ​ +(1-2^{-(n-1)})​ +(12(n1))
反码 − ( 2 n − 1 − 1 ) -(2^{n-1}-1) (2n11) ~ + ( 2 n − 1 − 1 ) +(2^{n-1}-1) +(2n11) − ( 1 − 2 − ( n − 1 ) ) -(1-2^{-(n-1)}) (12(n1)) ~ + ( 1 − 2 − ( n − 1 ) ) ​ +(1-2^{-(n-1)})​ +(12(n1))
补码 − 2 n − 1 -2^{n-1} 2n1 ~ + ( 2 n − 1 − 1 ) ​ +(2^{n-1}- 1)​ +(2n11) − 1 -1 1 ~ + ( 1 − 2 − ( n − 1 ) ) ​ +(1-2^{-( n - 1 )})​ +(12(n1))
移码 − 2 n − 1 -2^{ n - 1 } 2n1 ~ + ( 2 n − 1 − 1 ) +(2^{ n - 1 } -1 ) +(2n11) − 1 -1 1 ~ + ( 1 − 2 − ( n − 1 ) ) +(1-2^{-( n - 1 )}) +(12(n1))

可以看见,定点数的补码和移码都能表示 2 n 2^n 2n个数,而原码和反码由于0占用了两个编码所以仅能表示 2 n − 1 2^n-1 2n1个数。

浮点数

小数点位置不固定的数就是浮点数,它的思想是基于在十进制中一个数可以写成很多表现形式的原理。

例如83.125可以写成 1 0 3 × 0.083125 ​ 10^3 \times 0.083125​ 103×0.083125 1 0 4 × 0.0083125 ​ 10^4 \times 0.0083125​ 104×0.0083125等,同理,一个二进制数也可以写成多种表现形式,如二进制数1011.10101可以写成 2 4 × 0.101110101 ​ 2^4 \times 0.101110101​ 24×0.101110101 2 5 × 0.0101110101 ​ 2^5 \times 0.0101110101​ 25×0.0101110101 2 6 × 0.00101110101 ​ 2^6 \times 0.00101110101​ 26×0.00101110101等。很明显一个数的浮点形式的表示并不是唯一的,当小数点位置变化时,阶码也可以相应的改变,因此可以用多个浮点形式来表达同一个数。

由此得出规律,一个二进制数N可以表示为 N = 2 E × F ​ N = 2^E \times F​ N=2E×F,其中E被称为阶码,F称为尾数。用阶码和尾数来表示的数就被称为浮点数,这种表示法又叫做浮点表示法

在浮点表示法中,阶码为带符号的整数,尾数为带符号的纯小数。其格式如下:
Float Format

浮点数的表示范围主要由阶码决定,其精度则由尾数决定,为了充分利用尾数,通常将尾数的绝对值限定在 [ 0.5 , 1 ] [0.5,1] [0.5,1]区间。当尾数用补码表示时有以下两点注意:

  1. 若尾数 M ≥ 0,则规格化尾数形式为 M = 0.1...... . ( 2 ) ​ M = 0.1......._{(2)}​ M=0.1.......(2)

    即其区间在 [ 0.5 , 1 ] [0.5 , 1 ] [0.5,1]

  2. 若尾数 M < 0,则规格化尾数形式为 M = 1.0...... . ( 2 ) M = 1.0......._{(2)} M=1.0.......(2)

    即其区间在 [ − 1 , − 0.5 ] [-1, -0.5] [1,0.5]

上面提到的尾数形式都是二进制的开头。

如果浮点数的阶码(包括1位阶符)用R位移码表示,尾数(包括1位数符)用M位的补码表示,则这种浮点数的表示的最大正数: + ( 1 − 2 − M + 1 ) × 2 2 R − 1 − 1 +(1 - 2^{-M+1}) \times 2^{2^{R-1}-1} +(12M+1)×22R11;最小负数: − 1 × 2 2 R − 1 − 1 -1 \times 2^{2^{R-1}-1} 1×22R11

IEEE 754 浮点数标准

从上面就可以知道浮点数有很多种实现的方法,但现行浮点数最主要的标准就是IEEE 754。

其表示形式为: ( − 1 ) S × 2 E ( b 0 b 1 b 2 … b p − 1 ) (-1)^S \times 2^E(b_0 b_1 b_2 \dots b_{p-1}) (1)S×2E(b0b1b2bp1),其中:

  1. ( − 1 ) S (-1)^S (1)S为该浮点数的数符,当S为0是表示正,反之则为负数;
  2. E为指数(阶码),它用移码表示;
  3. 2 E ( b 0 b 1 b 2 … b p − 1 ) 2^E(b_0 b_1 b_2 \dots b_{p-1}) 2E(b0b1b2bp1)为尾数,长度为P位,用原码表示;

目前,计算机中主要用三种形式的浮点数:

参数单精度浮点数双精度浮点数扩充精度浮点数
浮点数字长326480
尾数长度P235264
符号位S111
指数长度E81115
指数范围-126 ~ 127-1022 ~ 1023-16382 ~ 16383
指数偏移量+127+1023+16383
可表示范围 1 0 − 38 10^{-38} 1038 ~ 1 0 38 10^{38} 1038 1 0 − 308 10^{-308} 10308 ~ 1 0 308 ​ 10^{308}​ 10308 1 0 − 4932 10^{-4932} 104932 ~ 1 0 4932 10^{4932} 104932

而编码值也分为三种不同情况:

  1. 规格化的值

    阶码不是全0或全1时,代表这就是一个规格化的值。如在单精度下:

    阶码为1011 0011时,偏移量为127(0111 1111),则其表示的真值为1011 0011-01111111=0011 0100,十进制即52.

    尾数部分约定小数点左边隐含有一位1,即尾数为**1.**开头(但实际上并不存在,只是一种约定),因此单精度浮点数有效位数为24位,不溢出情况下尾数值范围为: 1 ≤ M &lt; 2 1 \leq M &lt; 2 1M<2,该约定是一种获得额外精度的技巧。

    如: b 0 b 1 … b 22 = 01001001100010001001011 b_0 b_1 \dots b_{22}=0100100 1100 0100 0100 1011 b0b1b22=01001001100010001001011时,其对应的尾数为: 1 + 2 − 2 + 2 − 5 + 2 − 8 + 2 − 9 + 2 − 13 + 2 − 17 + 2 − 20 + 2 − 22 + 2 − 23 1+2^{-2}+2^{-5}+2^{-8}+2^{-9}+2^{-13}+2^{-17}+2^{-20}+2^{-22}+2^{-23} 1+22+25+28+29+213+217+220+222+223 = 1.28724038600921630859375。

  2. 非规格化的值

    阶码全0时,代表这是一个非规格化值,在这种情况下,指数的真值是1-偏移量(单精度为-126,双精度为-1022),尾数的值就是二进制的小数,不包含隐含的1。

    非规格化的值主要用于表示0,或非常接近0的值。因为规格化包含隐含的1,无法表示0

    实际上0.0的浮点表示是除了符号位以外全0,但-0.0则是符号位为1以外全0,也就是说说浮点数下±0.0在表示上是有不同的。

  3. 特殊值

    阶码全1时,表示特殊值。

    尾数部分全0时就表示无穷大,符号位用于表示正无穷或负无穷,在运算时溢出就会用无穷来表示。

    尾数部分不全为0时表示"NaN, Not a Number",即不是一个数。在运算时结果不是实数或者无穷就会用NaN来表示。

示例

下面示范如何用IEEE 754标准将176.0625表示为单精度浮点数:

先将十进制转换为二进制:

( 176.0625 ) 10 = ( 10110000.0001 ) 2 (176.0625)_{10} = (10110000.0001)_2 (176.0625)10=(10110000.0001)2

然后对数进行规格化处理(即尾数小数点左边隐含一位1的表示形式,并满足尾数占23位长度的规定):

( 10110000.0001 ) 2 = ( 1.01100000001000000000000 × 2 7 ) 2 (10110000.0001)_2 = (1.01100000001000000000000 \times 2^7)_2 (10110000.0001)2=(1.01100000001000000000000×27)2

然后求阶码,标准规定阶码以移码方式表示,单精度浮点数规定偏移量127,即:

7(指数)+127(偏移量) = ( 134 ) 10 = ( 10000110 ) 2 (134)_{10} = (10000110)_2 (134)10=(10000110)2

最后,拼接起来即可得到 ( 176.0625 ) 10 ​ (176.0625)_{10}​ (176.0625)10的单精度浮点数二进制:

符号位 S阶码 E尾数 P
01000011001100000001000000000000

浮点数运算

设有浮点数 X = M × 2 j , Y = N × 2 j X = M \times 2^j , Y = N \times 2^j X=M×2j,Y=N×2j,求X±Y的运算过程要经过如下步骤:

  1. 对阶

    使两个数的阶码相同,令 K = ∣ i − j ∣ K=|i-j| K=ij,把阶码小的数的尾数右移K位,使其阶码加上K。

  2. 求尾数和(差)

    尾数相加/相减

  3. 结果规格化,判断是否溢出

    如果运算结果非规格化值,则规格化。当尾数溢出则调整阶码。

  4. 舍入处理

    对结果向右规格化时,尾数的最低位将被丢弃。另外,对阶也可能出现右移导致丢失低位。舍入是为了求出最低的运算误差。

  5. 溢出判别

    以阶码为准,若阶码溢出,则运算结果溢出;若阶码小于最小值,则结果为0;否则结果正确。

而相乘则是乘数的阶码相加,尾数相乘;相除则是被除数减去除数阶码作为商的阶码,商的尾数等于被除数尾数除以除数;

同样的,乘除运算都要进行规格化处理并判断是否溢出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值