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

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

    浮点型变量在计算机内存中占用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操作,将会发生下溢。

 

时间: 2024-08-03 23:11:52

c语言中float、double、long double在内存中存储方式的相关文章

c语言-C语言中float类型浮点数

问题描述 C语言中float类型浮点数 请问C语言中float类型浮点数的阶码为什么要使用移码表示,这样表示的优点是什么? 解决方案 浮点数的表示中为什么要用移码表示阶码? 解决方案二: 如果阶码(指数)也用补码来表示,就会使得一个浮点数中出现两个符号位:浮点数自身的和浮点数指数部分的.这样的结果是,在比较两个浮点数大小时,无法像比较整数时一样使用简单的无逻辑的二进制比较. http://www.zhihu.com/question/24115452 解决方案三: 因为浮点数正负之分啊

C语言中static的作用及C语言中使用静态函数有何好处_C 语言

想了解Java中static关键字的作用和用法详细介绍,请点击此处了解详情. 在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条,分别是: 一是隐藏功能,对于static修饰的函数和全局变量而言 二是保持持久性功能,对于static修饰的局部变量而言. 三是因为存放在静态区,全局和局部的static修饰的变量,都默认初始化为0 下面我逐一给大家介绍: (1)先来介绍它的第一条也是最重要的一条:隐藏. 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有

求c语言乱码-C语言中的float数据类型

问题描述 C语言中的float数据类型 在C语言中float数据用32位存储,其中6位为小数位,说明小数点后的值不能超过2^6-1.但实际上却是能保留小数点后6位,这是怎么回事? 解决方案 http://blog.csdn.net/qq_27183003/article/details/49506547http://www.cnblogs.com/jillzhang/archive/2007/06/24/793901.html 解决方案二: c语言数据类型C语言数据类型C语言基本数据类型int

md5-关于C语言中MD5算法怎么应用

问题描述 关于C语言中MD5算法怎么应用 在项目中要给一个成员变量AuthenticatorSource赋值,然后阅读文档后有如下说明: AuthenticatorSource:用于鉴别源地址.其值通过单向MD5hash计算得出,表示如下: AuthenticatorSource = MD5(Source_Addr+9 字节的0 +shared secret+timestamp) Sharedsecret 由中国移动与源地址实体事先商定,timestamp格式为:MMDDHHMMSS,即月日时分

c语言-C语言中的float数据类型

问题描述 C语言中的float数据类型 C语言中的float数据用32位存储,其中有6位为小数位,那么小数点后的值应该不超过2^6-1,而实际上却是保留小数点后6位,这是怎么回事? 解决方案 你的问题本身就不对,float的位数精度是23位,也就是1/2^23,折算成10进制,在1/10^6.x,为了不丢失最后的那一点精度,所以用7位表示尾数而不是6位.http://blog.csdn.net/dxy612/article/details/5518477 解决方案二: 首先我的观点同上,补充一点

c++-C++ float类型和double类型的输出

问题描述 C++ float类型和double类型的输出 在VS2012下,用cout<<输出float和double,为什么精度都只有6位? 解决方案 http://blog.sina.com.cn/s/blog_a459dcf501013g39.htmlhttp://wenda.so.com/q/1371005504064718 解决方案二: setprecision Sets the decimal precision used to represent floating-point v

在输入一个实数,输出对应的double和float类型在内存中的二进制内容

问题描述 在输入一个实数,输出对应的double和float类型在内存中的二进制内容 在输入一个实数,输出对应的double和float类型在内存中的二进制内容 解决方案 #include <iostream> using namespace std; int main() { double x = 1.234; float y = 1.234; char * a = (char *)(void *)&x; char * b = (char *)(void *)&y; cout

c语言中for循环设置步长以后,自变量不按步长累加是怎么回事

问题描述 c语言中for循环设置步长以后,自变量不按步长累加是怎么回事 源代码为: #include #include float C[20]; int main() { float dx,dt,t,u[20],u_1[20],u_2[20]; int n,;float L[20],*p; float*TIME(float A[]); dt=0.01;dx=2*M_PI/20; for(n=0;n<=19;n++) { u[n]=sin(n*dx); } for(t=dt;;t=t+dt) {

数据类型-c语言中,二进制文件中怎样判断的各个数据的类型

问题描述 c语言中,二进制文件中怎样判断的各个数据的类型 我有一个二进制文件,包含各种数字,stirng char.但是我不知道里面的各个数据的类型,只知道各个数据的名字.然后怎么判断各个数据的类型.(比如 8bit 的 char, 16 bit 的 boolean 之类的)然后再转成要求的数据类型输出(printf). 我打算先用fread一条一条读取这些文件到结构体数组中,.主要问题是我不知道各个数据的类型,用不了fread!!! 老师给的提示是说,先把二进制文件转成十六进制或其他格式 查看