【高级阶段】第20章 数据的机器级表示

目录

20 数据的机器级表示

20.1 补码讲解及内存实战

20.2 整型类型溢出解析

20.2.1 整型不同类型

20.2.2 整数型溢出解析

20.3 浮点数IEEE754标准解析及实战计算演示

20.4 浮点数精度丢失实战演示

20.4.1 浮点型变量的数值范围及精度*

20.4.2 浮点数精度丢失

20.5 选择题真题

20 数据的机器级表示

20.1 补码讲解及内存实战

补码:原码取反加一。表示负数。CPU中的内存地址是32位的。以2+(-5)举例:当最高位为1(代表负数)时,要得到原码才能知道0xfffffffd的值,即对其取反后加1得到3,所以其值为−3。

#include <stdio.h>

int main(){
    int i,j,k;
    i=2;
    j=-5;
    k=i+j;
    printf("%d",k);
    return 0;
}

小端法存储在内存中:

 

反码

正数的反码和原码一样;负数的反码就是在原码的基础上符号位保持不变,其他位取反。

 

20.2 整型类型溢出解析

20.2.1 整型不同类型

 

整型变量包括6种类型,类型长度也不同,各长度的范围也不同,以short类型为例:

 

有符号和无符号的short类型能够表示的最大数范围

有符号的short类型的最小的数:1000 0000 0000 0000   ---   -32768。

有符号的short类型的最大的数:0111 1111 1111 1111   ---   32767。

以此类推,各类数据类型的范围如下:

类型说明符

占用的内存空间

整型数范围

int

4字节

-231 ~ 231-1

short

2字节

-32768~32767 【-215 ~ 215-1】

long

4字节/x86;8字节/x64

-231 ~ 231-1 或 -263 ~ 263-1

unsigned int

4字节

0 ~ 232-1

unsigned short

2字节

0~65535 【0 ~ 216-1】

unsigned long

4字节/x86;8字节/x64

0 ~ 232-1 或 0 ~ 264-1

20.2.2 整数型溢出解析

超过最大范围就会发生溢出,如果发生溢出,则需要将数存储在更大的空间中。比如若超过short类型范围,可以将变量的值存储在int类型中,int存储在double中。

#include <stdio.h>

int main() {
    int i;
    short a = 32767;//最高也只有32767
    short b;
    b = a + 1;//如果存储在同类型的b中一定会发生溢出
    i = a + 1;//解决溢出的办法就是将a的值存储在更大的空间中
    printf("b = a + 1 = %d\n", b);
    printf("i = a + 1 = %d\n", i);
    printf("--------------\n");
    //下面是无符号数
    unsigned short n = 0x8056;//无符号类型,最高位不认为是符号位
    b = 0x8056;//1000 0000 0101 0110  --- 328554(无符号)
    //0111 1111 1010 1010  --- 32682
    printf("b=%d\n", b);//b是有符号类型,所以输出是负值
    printf("n=%u\n", n);//无符号类型要用%u,用%d是不规范的
    return 0;
}

20.3 浮点数IEEE754标准解析及实战计算演示

使用float关键字或double关键字定义浮点型变量。

类型

float

double

占用的内存空间

4字节

8字节

与整型数据的存储方式不同,浮点型数据是按照指数形式存储的。IEEE-754浮点型变量存储标准如下:

 

IEEE-754浮点型变量存储标准

IEEE-754的规定:

指数部分的值只能是1~254,不能是全0,全1。指数部分运算前都要减去127,因为还要表示负指数。

小数部分的底数左边省略存储一个1。

【例题1】:

S

阶码

尾数

0

10000001

0010 0000 0000 0000 0000 000

也可以变成如下形式:

浮点数4.5的存储结果

格式

SEEEEEEE

EMMMMMMM

MMMMMMMM

MMMMMMMM

二进制数

01000000

10010000

00000000

00000000

十六进制数

40

90

00

00

S:0,表示正数。

E:10000001 --- 129(十进制),129-127=2,表示2的2次幂。

M:0010 0000 0000 0000 0000 000,实际是1.0010 0000 0000 0000 0000 000 --- 1.125(.001---2-3=0.125)。

最终结果:1.125 × 22 = 4.5。

【例题2】:

 

f1 = 1.456在内存中存储的值是:1.45599997,十六进制:0x3fba5e35,转化为二进制也就是:0011 1111 1011 1010 0101 1110 0011 0101。

浮点数1.456的存储结果

格式

SEEEEEEE

EMMMMMMM

MMMMMMMM

MMMMMMMM

二进制数

001111111

10111010

01011110

00110101

十六进制数

3f

ba

5e

35

S=0;

E=0111 1111 --- 127; //2E-127=20。

M=1.011 1010 0101 1110 0011 0101。20+2-2+2-3+2-4+2-6+... 近似一个浮点数

最终结果:≈1.45599997。

20.4 浮点数精度丢失实战演示

20.4.1 浮点型变量的数值范围及精度*

类型说明符

位数

数值范围

有效数字(精度)

float

32(4字节)

10-37 ~ 1038【2-126 ~ 2127

6~7位(指十进制的)

double

64位(8字节)

10-307 ~ 10308【2-1022 ~ 21023】

15~16位(指十进制的)

float类型说明:

数值范围是2-126 ~ 2127:因为在IEEE-754标准中,指数部分的范围1 ~ 254,并且指数部分运算前都要减去127,也就是1-127 ~ 254-127,最终得到的幂的范围是:-126 ~ 127。

有效数字是6~7位:23位的小数部分表示的是223=8,388,608,有7位,因此,化得净的有效数字是7位,化不净的有效数字是6位,因为最后一位有舍入误差

20.4.2 浮点数精度丢失

【例】:验证精度丢失现象的程序

#include <stdio.h>

int main() {
    float a = 1.23456789e10; //正常a = 12345678900
    float b;
    b = a + 20;//正常b = 12345678920
    printf(" b = a + 20 = %f\n", b); //但结果是 1.23456788e+10
    return 0;
}

调试结果:

 

可以看出a在赋值之后的结果就发生了精度丢失。解决办法就是将值存储在更大的精度中比如double类型中。

另外针对强制类型转换,int转float可能造成精度丢失,因为int是有10位有效数字的,但是int强制转为double不会,float转为double也不会丢失精度。

20.5 选择题真题

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白帽菜菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值