c语言中float、double、long double在内存中存储方式

简介: 存储格式中的二机制转为浮点数:     浮点型变量在计算机内存中占用4个字节(4 Byte),即32-bit,一个浮点数由2部分组成:底数m  和 指数e;   底数部分:使用2进制数来表示此浮点数的实际值;   指数部分:占用8=bit空间来表示,表示数值范围:0-255;后面介绍 用于存储...

存储格式中的二机制转为浮点数:

    浮点型变量在计算机内存中占用4个字节(4 Byte),即32-bit,一个浮点数由2部分组成:底数m  和 指数e;

  底数部分:使用2进制数来表示此浮点数的实际值;

  指数部分:占用8=bit空间来表示,表示数值范围:0-255;后面介绍 用于存储科学计数法中的指数部分,并且采用移位存储方式;

具体分析:

  浮点数据就是按下表的格式存储在4个字节中:

  Address+0 Address+1 Address+2 Address+3 Contents

  SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
      S部分: 表示浮点数正负,1为负数,0为正数。一位即可

  E部分:指数加上127后的值的二进制数(why是加上了127之后的值? 由于指数应可正可负,所以IEEE规定,此处算出的次方须减去127才是真正的指数。所以float的指数可从 -126到128.)

  M部分:24-bit的底数(底数部分实际是占用24-bit的一个值,由于其最高位始终为 1 ,所以最高位省去不存储,在存储中只有23-bit。)

  特例:浮点数 为0时,指数和底数都为0,但此前的公式不成立。因为2的0次方为1,所以,0是个特例。这个特例也不用认为去干扰,编译器会自动去识别。

 举例:看下-12.5在计算机中存储的具体数据:0xC1 0x48 0x00 0x00

  二进制:11000001 01001000 00000000 00000000

   格式:SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM

  可见:

    S: 为1,是个负数。

    E:(8-bit)为 10000010 转为10进制为130,130-127=3,即实际指数部分为3.

    M:(23-bit)为 10010000000000000000000。底数实际上是:1.10010000000000000000000

  现在,我们通过指数部分E的值来调整底数部分M的值。

    调整方法为:如果指数E为负数,底数的小数点向左移,如果指数E为正数,底数的小数点向右移。小数点移动的位数由指数E的绝对值决定。

    这里,E为正3,使用向右移3为即得: 1100.10000000000000000000

  转换过程:小数点左边的1100 表示为 (1 × 2^3) + (1 × 2^2) + (0 × 2^1) + (0 × 2^0), 其结果为 12 。

        小数点右边的 .100… 表示为 (1 × 2^-1) + (0 × 2^-2) + (0 × 2^-3) + ... ,其结果为.5 。

   以上二值的和为12.5, 由于S 为1,使用为负数,即-12.5 。所以,16进制 0XC1480000 是浮点数 -12.5 。

浮点数转存储格式的二进制数:

  下面看下如何将一浮点数装换成计算机存储格式中的二进制数。 举例将17.625换算成 float型。

  1、转为二进制:10001.101

  2、小数点,左移4位,变成1.0001101

  3、这样底数为:1.0001101, 指数为:4+127=131,二进制位:1000011

  4、符号位为0,因为是正数;

  5、合并:0 1000011  0001101后面补0,补成32-bit;

  6、转成16进制:转换成16进制:0x41 8D 00 00 

浮点数转成二进制代码形式代码:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 #define uchar unsigned char
 5 
 6 void binary_print(uchar c)
 7 {
 8         for(int i = 0; i < 8; ++i)
 9         {
10                 if((c << i) & 0x80)
11                         cout << '1';
12                 else cout << '0';
13         }
14         cout << ' ';
15 }
16 
17 int main()
18 {
19         float a;
20         uchar c_save[4];
21         uchar i;
22         void *f;
23         f = &a;
24 
25         cout<<"pls input a float num:";
26         for(i=4;i!=0;i--)
27                 binary_print(c_save[i-1]);
28         cout<<endl;
29 
30         return 0;
31 }

  C标准规定,float类型必须至少能表示6位有效数字,就像33.333 333这样的数字的小数点后的前6位;那么whyfloat能表示6位有效数字呢?

   解释如下:十进制中的9,在二进制中的表示形式是1001,这也就是说: 表示十进制中的一位数在二进制中需要4bit,所以我们现在float中具有24bit的精度,所以float在十进制中具有24/4=6,所以在十进制里,float能够精确到小数点后6位;

  double呢?其实和float原理是一样的,只是double的位数更长一些而已;

        

   注意点,double类型数据操作比float型运算要慢很多;

浮点值的上溢和下溢

  假设系统中最大的float值为34E38,并进行如下操作:

    float toobig = 3.4E38 * 100.0f ;

           printf("%e\n", toobig);

  会发生什么呢?这是一个上溢(overflow)的例子。当计算结果是一个大得不能表达的数时,会发生上溢。

   相对应的,当表示一个float能表示的最小数时,对这个数进行除2操作,将会发生下溢。

 

相关文章
|
2月前
|
存储 编译器 C语言
C语言存储类详解
在 C 语言中,存储类定义了变量的生命周期、作用域和可见性。主要包括:`auto`(默认存储类,块级作用域),`register`(建议存储在寄存器中,作用域同 `auto`,不可取地址),`static`(生命周期贯穿整个程序,局部静态变量在函数间保持值,全局静态变量限于本文件),`extern`(声明变量在其他文件中定义,允许跨文件访问)。此外,`typedef` 用于定义新数据类型名称,提升代码可读性。 示例代码展示了不同存储类变量的使用方式,通过两次调用 `function()` 函数,观察静态变量 `b` 的变化。合理选择存储类可以优化程序性能和内存使用。
149 82
|
13天前
|
存储 C语言
使用 sizeof 操作符计算int, float, double 和 char四种变量字节大小
【10月更文挑战第13天】使用 sizeof 操作符计算int, float, double 和 char四种变量字节大小。
47 1
|
19天前
|
存储 C语言
深入C语言内存:数据在内存中的存储
深入C语言内存:数据在内存中的存储
|
2月前
|
存储 人工智能 C语言
数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值&&特殊矩阵的压缩存储
本文首先介绍了栈的应用之一——括号匹配,利用栈的特性实现左右括号的匹配检测。接着详细描述了南京理工大学的一道编程题,要求判断输入字符串中的括号是否正确匹配,并给出了完整的代码示例。此外,还探讨了栈在表达式求值中的应用,包括中缀、后缀和前缀表达式的转换与计算方法。最后,文章介绍了矩阵的压缩存储技术,涵盖对称矩阵、三角矩阵及稀疏矩阵的不同压缩存储策略,提高存储效率。
283 8
|
26天前
|
存储 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天】