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

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 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

目录
相关文章
|
11天前
|
存储 程序员 编译器
C 语言中的数据类型转换:连接不同数据世界的桥梁
C语言中的数据类型转换是程序设计中不可或缺的一部分,它如同连接不同数据世界的桥梁,使得不同类型的变量之间能够互相传递和转换,确保了程序的灵活性与兼容性。通过强制类型转换或自动类型转换,C语言允许开发者在保证数据完整性的前提下,实现复杂的数据处理逻辑。
|
11天前
|
存储 编译器 程序员
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
在C语言中,内存布局是程序运行时非常重要的概念。内存布局直接影响程序的性能、稳定性和安全性。理解C程序的内存布局,有助于编写更高效和可靠的代码。本文将详细介绍C程序的内存布局,包括代码段、数据段、堆、栈等部分,并提供相关的示例和应用。
25 5
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
|
11天前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
39 6
|
12天前
|
存储 数据管理 C语言
C 语言中的文件操作:数据持久化的关键桥梁
C语言中的文件操作是实现数据持久化的重要手段,通过 fopen、fclose、fread、fwrite 等函数,可以实现对文件的创建、读写和关闭,构建程序与外部数据存储之间的桥梁。
|
15天前
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
36 6
|
15天前
|
存储 数据建模 程序员
C 语言结构体 —— 数据封装的利器
C语言结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个整体。它支持数据封装,便于管理和传递复杂数据,是程序设计中的重要工具。
|
21天前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
81 12
|
13天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
37 1
|
15天前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
15天前
|
大数据 C语言
C 语言动态内存分配 —— 灵活掌控内存资源
C语言动态内存分配使程序在运行时灵活管理内存资源,通过malloc、calloc、realloc和free等函数实现内存的申请与释放,提高内存使用效率,适应不同应用场景需求。