【C语言】你知道浮点数是怎么存储的吗?(上)

简介: 【C语言】你知道浮点数是怎么存储的吗?

前言

🎈大家好,我是何小侠🎈

🍃大家可以叫我小何或者小侠🍃

💐希望能通过写博客加深自己对于学习内容的理解💐

🌸也能帮助更多人理解和学习🌸

花繁柳密处,拨得开,才是手段;风狂雨急时,立得定,方见脚根。

解释:在花繁叶茂、柳密如织的美丽和复杂情境下,如果还能不受束缚,来去自如,才是有手段、有办法的人。在狂风骤雨的狼狈状态下还能站稳脚跟,不被吹倒,才是真正有原则的大英雄。


    这篇博客我们将会了解到数据在内存中的存储方式。这对我们调试和理解内存都有很大好处。

    常见的浮点数🍀

    例如:1.2233344

    又如:1E3

    1E3我们应该好好介绍一下:

    实际上就是我们初中物理中学习的科学计数法,

    就等于1 x 10^3 = 1000。

    还有一点规定,就是E前面的数字可以是小数,而E后面的数字只能是整数

    这与我们写物理题目是一个道理,毕竟我们从来没有都不会让小数成为

    10的指数。

    我所使用的编译器是VS2022,我们如果想知道我们编译器所规定的数据类型的最大值最小值可以查找两个头文件。

    1. limits.h是用来查看除浮点型以外的数据类型的。

    由于我们的重点是浮点数,就不一一展示了

    1. float.h就是用来查看编译器所设定的浮点数的最大值最小值的,但是在VS2022上很难查找到这个文件,所以我借助了everything这个很好用的查找文件的工具。

    我们已经学会了如何查看头文件,接下来我们再来看一个例子。

    引例🐽

    int main()
    {
     int n = 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);
     return 0;
    }

    我们看看这行代码,再分析一下。

    下面是我的分析图,你也可以看看。

    • 我们先看上面部分

      我们 printf("n的值为:%d\n", n);
      这行代码是比较简单的,输出9,
      那么 printf("*pFloat的值为:%f\n", *pFloat);这一行就有点不确定了,我们知道如果以%d打印,那么我们要打印的数据在%d看来就是一个有有符号整型或者以%u打印,那么要打印的数据在%u看来就是一个无符号的整型。
      这里应该也是一样的,那么以%f来打印,是打印9.000000吗?我们暂时放一放看下半部分。
    • 下半部分

      我们知道*pfloat = 9.0会改变这两个变量里的数据,那么float *类型的是比较容易改变的,会被直接改变变成9.000000,但是int 类型的变量n呢?如果你不了解浮点数在内存中的存储,你确实很难知道为什么。
      我们先将答案给出来,大家带着答案一起去寻找为什么

    引例答案✳️

    这真的很奇怪是不是,第二行和第三行好像是完全没有道理。但是如果你仔细一想就应该能推提出一个假设浮点数的存储方式一定与整型不同。

    别急我们马上就来介绍。

    浮点数的存储规则💥

    我们想搞懂这个问题需要我们了解浮点数在内存中的存储方法

    放心不是很复杂,只要我们用点心。

    在C语言中,浮点数的存储方式遵循IEEE 754标准。具体来说,C语言中的浮点数类型(如float、double)使用二进制表示,并按照IEEE 754标准进行存储。

    IEEE 754规定:

    任何一个二进制浮点数N都可以表达成下面的方式:

    (-1) ^ S * M * 2 ^ E

    • 在这个式子中(-1) ^ S表示符号位,当S为0时,N为正数,当S为1时,N为负数。
    • M表示的是有效位数,大于1,小于2。
    • 2 ^ E表示指数位。

    这样你肯定也还是不明白,没关系我们举例就行。

    首先我们也还是需要复习一下我们的数学知识:

    我们更仔细的来看就是这样的:

    那么如果十进制是这样那么二进制呢?

    当然是差不多的,我们再来举个例子

    如果不是很懂可以看这副图


    目录
    相关文章
    |
    2月前
    |
    存储 编译器 C语言
    C语言存储类详解
    在 C 语言中,存储类定义了变量的生命周期、作用域和可见性。主要包括:`auto`(默认存储类,块级作用域),`register`(建议存储在寄存器中,作用域同 `auto`,不可取地址),`static`(生命周期贯穿整个程序,局部静态变量在函数间保持值,全局静态变量限于本文件),`extern`(声明变量在其他文件中定义,允许跨文件访问)。此外,`typedef` 用于定义新数据类型名称,提升代码可读性。 示例代码展示了不同存储类变量的使用方式,通过两次调用 `function()` 函数,观察静态变量 `b` 的变化。合理选择存储类可以优化程序性能和内存使用。
    153 82
    |
    30天前
    |
    存储 C语言
    深入C语言内存:数据在内存中的存储
    深入C语言内存:数据在内存中的存储
    |
    2月前
    |
    存储 人工智能 C语言
    数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值&&特殊矩阵的压缩存储
    本文首先介绍了栈的应用之一——括号匹配,利用栈的特性实现左右括号的匹配检测。接着详细描述了南京理工大学的一道编程题,要求判断输入字符串中的括号是否正确匹配,并给出了完整的代码示例。此外,还探讨了栈在表达式求值中的应用,包括中缀、后缀和前缀表达式的转换与计算方法。最后,文章介绍了矩阵的压缩存储技术,涵盖对称矩阵、三角矩阵及稀疏矩阵的不同压缩存储策略,提高存储效率。
    350 8
    |
    1月前
    |
    存储 C语言
    C语言中的浮点数存储:深入探讨
    C语言中的浮点数存储:深入探讨
    |
    2月前
    |
    存储 算法 C语言
    数据结构基础详解(C语言): 二叉树的遍历_线索二叉树_树的存储结构_树与森林详解
    本文从二叉树遍历入手,详细介绍了先序、中序和后序遍历方法,并探讨了如何构建二叉树及线索二叉树的概念。接着,文章讲解了树和森林的存储结构,特别是如何将树与森林转换为二叉树形式,以便利用二叉树的遍历方法。最后,讨论了树和森林的遍历算法,包括先根、后根和层次遍历。通过这些内容,读者可以全面了解二叉树及其相关概念。
    |
    2月前
    |
    存储 机器学习/深度学习 C语言
    数据结构基础详解(C语言): 树与二叉树的基本类型与存储结构详解
    本文介绍了树和二叉树的基本概念及性质。树是由节点组成的层次结构,其中节点的度为其分支数量,树的度为树中最大节点度数。二叉树是一种特殊的树,其节点最多有两个子节点,具有多种性质,如叶子节点数与度为2的节点数之间的关系。此外,还介绍了二叉树的不同形态,包括满二叉树、完全二叉树、二叉排序树和平衡二叉树,并探讨了二叉树的顺序存储和链式存储结构。
    |
    2月前
    |
    存储 算法 C语言
    C语言手撕数据结构代码_顺序表_静态存储_动态存储
    本文介绍了基于静态和动态存储的顺序表操作实现,涵盖创建、删除、插入、合并、求交集与差集、逆置及循环移动等常见操作。通过详细的C语言代码示例,展示了如何高效地处理顺序表数据结构的各种问题。
    |
    2月前
    |
    存储 缓存 程序员
    c语言的存储类型-存储类
    本文详细介绍了C语言中的存储类型及其分类,包括基本类型(如整型、浮点型)和复合类型(如数组、结构体)。重点讲解了不同存储类别(`auto`、`static`、`register`、`extern`、`typedef`、`volatile`、`const`)的特点及应用场景,并展示了C11/C99引入的新关键字(如`_Alignas`、`_Atomic`等)。通过示例代码解释了每个存储类别的具体用法,帮助读者更好地理解和运用这些概念。
    |
    3月前
    |
    存储 API C语言
    【C语言】 作用域和存储期
    【8月更文挑战第18天】
    |
    3月前
    |
    存储 C语言
    【C语言】进程间通信之存储映射区mmap
    【C语言】进程间通信之存储映射区mmap
    40 0