C语言 — 数据在内存中的存储(2)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 本文延续 数据在内存中的存储(1)介绍关于浮点数在内存中的存储如果有帮助,还请各位小伙伴多多点赞关注收藏,后期会持续进行更新!!!本文内容1.浮点数类型介绍2.浮点数存储规则3.浮点数实例讲解4.IEEE 754的一些特别规定

前言

image.png


本文内容

image.png目录


前言

本文内容

浮点数在内存中的存储

一、浮点数类型

二、浮点数表示的范围

三、浮点数存储规则

1.浮点数二进制表示形式

2.浮点数在内存中的存储方式

单精度浮点型

双精度浮点型

3.IEEE 754的一些特别规定

指数E从内存中取出的三种情况:

四、实例讲解

1.实例代码

2.输出结果

3.代码解析

证明

代码解析

五、总结

六、完结


浮点数在内存中的存储


一、浮点数类型

image.png

二、浮点数表示的范围


浮点数表示范围的定义在来自于 float.h 的定义

image.png

三、浮点数存储规则


1.浮点数二进制表示形式


根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式

image.png

2.浮点数在内存中的存储方式


单精度浮点型

对于32位的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M。

image.png

双精度浮点型

对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。

image.png

3.IEEE 754的一些特别规定

IEEE 754对有效数字M和指数E,还有一些特别规定。


指数 M


前面说过, 1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中xxxxxx表示小数部分。


IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的

xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。


以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。


指数E

E为一个无符号整数(unsigned int)

这意味着,如果E为8位,它的取值范围为0->255;如果E为11位,它的取值范围为0->2047。


但是,我们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。


比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即

10001001。


指数E从内存中取出的三种情况:

E不全为 0 或不全为 1

image.png

00111111000000000000000000000000SEM

E全为0

image.png

E全为1

image.png

四、实例讲解


1.实例代码

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>intmain()
{
intn=9;
float*pFloat= (float*)&n;
printf("n的值为:%d\n",n);
printf("*pFloat的值为:%f\n",*pFloat);
*pFloat=9.0;
printf("num的值为:%d\n",n);
printf("*pFloat的值为:%f\n",*pFloat);
return0;
}

2.输出结果

image.png

3.代码解析


错误案例

整形在内存中的存储方式分析

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>intmain()
{
intn=9;                                 //整形  9float*pFloat= (float*)&n;               //取出n的地址 再强转成float * 浮点数指针类型 printf("n的值为:%d\n",n);                 //假设  输出9printf("*pFloat的值为:%f\n",*pFloat);     //假设  输出9.000000*pFloat=9.0;                             //解引用改变地址内的数据   从9——>9.0                    printf("num的值为:%d\n",n);               //假设  输出9printf("*pFloat的值为:%f\n",*pFloat);     //假设  输出9.000000return0;
}

证明

因为整形在内存的存储方式浮点数在内存的存储方式不同,从而导致输出的结果于上面的假设输出存在差异。

n//假设输出 9            最终输出  9*pFloat(第一次)//假设输出 9.000000  最终输出  0.000000*pFloat=9.0;              //解引用改变地址内的数据   从9——>9.0        num//假设输出 9         最终输出  1091567616*pFloat(第二次)//假设输出 9.000000  最终输出   9.000000

结果除了 n 和 *pFloat(第二次)输出跟假设的相同,从输出结果证明整形和浮点数在内存中的存储方式是不同的。


代码解析

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h>intmain()
{
intn=9;
float*pfloat= (float*)&n;
//强制类型转换成float*类型printf("n的值为:%d\n", n);
// n 本来是int类型  9    存入内存时  二进制表示  0000 0000 0000 0000 0000 0000 0000 1001//通过%d  形式输出   正数原反补相同   最终输出   9  ✔printf("*pfloat的值为:%f\n", *pfloat);
//存入使是以整形类型存放的  9  二进制表示为  0000 0000 0000 0000 0000 0000 0000 1001 //当取出时以浮点数形式取出  //由于指数E全为0,所以符合上一节的第二种情况。//因此,浮点数V就写成://V = (-1) ^ 0 × 0.00000000000000000001001×2 ^ (-126) = 1.001×2 ^ (-146)//显然,V是一个很小的接近于0的正数,所以用十进制小数表示就是0.000000*pfloat=9.0;
printf("num的值为:%d\n", n);
//这里存入内存时是以float类型存入的   浮点数 9.0 -> 1001.0  -> 1.001*2^3//9.0 -> 1001.0 ->(-1)^01.0012^3 -> s=0, M=1.001,E=3+127=130//0 10000010 001 0000 0000 0000 0000 0000//整形输出 得1091567616printf("*pfloat的值为:%f\n", *pfloat);
//存入和取出使都是浮点型    所以结果是9.000000return0;
}

五、总结

image.png

六、完结

image.png

目录
相关文章
|
7天前
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
28 11
|
1天前
|
存储 数据建模 程序员
C 语言结构体 —— 数据封装的利器
C语言结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个整体。它支持数据封装,便于管理和传递复杂数据,是程序设计中的重要工具。
|
30天前
|
监控 算法 应用服务中间件
“四两拨千斤” —— 1.2MB 数据如何吃掉 10GB 内存
一个特殊请求引发服务器内存用量暴涨进而导致进程 OOM 的惨案。
|
28天前
|
C语言
【c语言】动态内存管理
本文介绍了C语言中的动态内存管理,包括其必要性及相关的四个函数:`malloc`、``calloc``、`realloc`和`free`。`malloc`用于申请内存,`calloc`申请并初始化内存,`realloc`调整内存大小,`free`释放内存。文章还列举了常见的动态内存管理错误,如空指针解引用、越界访问、错误释放等,并提供了示例代码帮助理解。
38 3
|
29天前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
60 1
|
1月前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
30天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
25 0
|
6月前
|
存储 C语言
C语言中的数据输入输出
C语言中的数据输入输出
80 0
|
缓存 C语言
C语言——数据的输入输出
C语言——数据的输入输出
|
C语言
C语言 字符数据输入输出
C语言 字符数据输入输出
117 0
C语言 字符数据输入输出