float和double的精度

float和double的精度1 范围 float 和 double 的范围是由指数的位数来决定的 float 的指数位有 8 位 而 double 的指数位有 11 位 分布如下 float 1bit 符号位 8bits 指数位 23bits 尾数位 double 1bit 符号位 11bits 指数位 52bits 尾数位 在数学中 特别是在计算机相关的数字 浮点数 问题的表述中 有

1 范围

float和double的范围是由指数的位数来决定的。 

float的指数位有8位,而double的指数位有11位,分布如下: 

float: 

1bit(符号位) 

8bits(指数位) 

23bits(尾数位) 

double: 

1bit(符号位)

11bits(指数位) 

52bits(尾数位) 

在数学中,特别是在计算机相关的数字(浮点数)问题的表述中,有一个基本表达法[1]:

 value of floating-point = significand x base ^ exponent , with sign — F.1 

  译为中文表达即为: 

 (浮点)数值 =      尾数    ×    底数 ^ 指数,(附加正负号)—————- F.2 

于是,float的指数范围为-127~128,而double的指数范围为-1023~1024,并且指数位是按补码的形式来划分的。其中负指数决定了浮点数所能表达的绝对值最小的数;而正指数决定了浮点数所能表达的绝对值最大的数,也即决定了浮点数的取值范围。 

float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;double的范围为-2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308。 

2 精度

float和double的精度是由尾数的位数来决定的。浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的“1”,由于它是不变的,故不能对精度造成影响。 

float:2^23 = ,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字; 

double:2^52 = 70496,一共16位,同理,double的精度为15~16位。 

单精度类型(float)和双精度类型(double)存储 

2009-11-24 13:57 

C 语言和C#语言中,对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用32bit, double数据占用64bit,我们在声明一个变量float f= 2.25f的时候,是如何分配内存的呢?如果胡乱分配,那世界岂不是乱套了么,其实不论是float还是double在存储方式上都是遵从IEEE的规范 的,float遵从的是IEEE R32.24 ,而double 遵从的是R64.53。 

    无论是单精度还是双精度在存储中都分为三个部分: 

  1. 符号位(Sign) : 0代表正,1代表为负 
  2. 指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储 
  3. 尾数部分(Mantissa):尾数部分

其中float的存储方式如下图所示: 

 image 

而双精度的存储方式为: 

 image 

     R32.24和R64.53的存储方式都是用科学计数法来存储数据的,比如8.25用十进制的科学计数法表示就为:8.25*100,而120.5可以表示为:1.205*102, 这些小学的知识就不用多说了吧。而我们傻蛋计算机根本不认识十进制的数据,他只认识0,1,所以在计算机存储中,首先要将上面的数更改为二进制的科学计数 法表示,8.25用二进制表示可表示为1000.01,我靠,不会连这都不会转换吧?那我估计要没辙了。120.5用二进制表示为:.1用 二进制的科学计数法表示1000.01可以表示为1.0001*23,.1可以表示为1.*26,任何一个数都的科学计数法表示都为1.xxx*2n, 尾数部分就可以表示为xxxx,第一位都是1嘛,干嘛还要表示呀?可以将小数点前面的1省略,所以23bit的尾数部分,可以表示的精度却变成了 24bit,道理就是在这里,那24bit能精确到小数点后几位呢,我们知道9的二进制表示为1001,所以4bit能精确十进制中的1位小数点, 24bit就能使float能精确到小数点后6位,而对于指数部分,因为指数可正可负,8位的指数位能表示的指数范围就应该为:-127-128了,所以 指数部分的存储采用移位存储,存储的数据为元数据+127,下面就看看8.25和120.5在内存中真正的存储方式。 

     首先看下8.25,用二进制的科学计数法表示为:1.0001*23 

按照上面的存储方式,符号位为:0,表示为正,指数位为:3+127=130 ,位数部分为,故8.25的存储方式如下图所示: 

 image 

而单精度浮点数120.5的存储方式如下图所示: 

 image 

那 么如果给出内存中一段数据,并且告诉你是单精度存储的话,你如何知道该数据的十进制数值呢?其实就是对上面的反推过程,比如给出如下内存 数据:000000,首先我们现将该数据分段,0 10000 0101 110 1101 0000 0000 0000 0000,在内存中的存储就为下图所示: 

 image 

根据我们的计算方式,可以计算出,这样一组数据表示为:1.*26=120.5 

而双精度浮点数的存储和单精度的存储大同小异,不同的是指数部分和尾数部分的位数。所以这里不再详细的介绍双精度的存储方式了,只将120.5的最后存储方式图给出,大家可以仔细想想为何是这样子的 

 image 

下面我就这个基础知识点来解决一个我们的一个疑惑,请看下面一段程序,注意观察输出结果 

            float f = 2.2f; 

            double d = (double)f; 

            Console.WriteLine(d.ToString(“0.0000000000000”)); 

            f = 2.25f; 

            d = (double)f; 

            Console.WriteLine(d.ToString(“0.0000000000000”)); 

可 能输出的结果让大家疑惑不解,单精度的2.2转换为双精度后,精确到小数点后13位后变为了2.37,而单精度的 2.25转换为双精度后,变为了2.00,为何2.2在转换后的数值更改了而2.25却没有更改呢?很奇怪吧?其实通过上面关于两 种存储结果的介绍,我们已经大概能找到答案。首先我们看看2.25的单精度存储方式,很简单 0 1000 0001 001 0000 0000 0000 0000 0000,而2.25的双精度表示为:0 100 0000 0001 0010 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000,这样2.25在进行强制转换的时候,数值是不会变的,而我们再看看2.2呢,2.2用科学计数法表示应该为:将十进制的小数转换为二进制的小数 的方法为将小数*2,取整数部分,所以0.282=0.4,所以二进制小数第一位为0.4的整数部分0,0.4×2=0.8,第二位为0,0.8*2= 1.6,第三位为1,0.6×2 = 1.2,第四位为1,0.2*2=0.4,第五位为0,这样永远也不可能乘到=1.0,得到的二进制是一个无限循环的排列 000… ,对于单精度数据来说,尾数只能表示24bit的精度,所以2.2的float存储为: 

 image 

但 是这样存储方式,换算成十进制的值,却不会是2.2的,应为十进制在转换为二进制的时候可能会不准确,如2.2,而double类型的数 据也存在同样的问题,所以在浮点数表示中会产生些许的误差,在单精度转换为双精度的时候,也会存在误差的问题,对于能够用二进制表示的十进制数据,如 2.25,这个误差就会不存在,所以会出现上面比较奇怪的输出结果。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/207234.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午2:16
下一篇 2026年3月19日 下午2:17


相关推荐

  • java如果智慧小区物业系统,基于ssm\springboot智慧小区物业管理平台实现

    java如果智慧小区物业系统,基于ssm\springboot智慧小区物业管理平台实现手把手实现智慧小区物业平台

    2022年10月17日
    2
  • 通俗语言说BM3D

    通俗语言说BM3D随着友商某以摄像著称的旗舰机型的发布,其SOC中ISP5.0采用的所谓单反级降噪算法BM3D一下火热起来,本文试图用尽量通俗易懂的语言从算法原理的角度揭开BM3D算法的神秘面纱。本文结构如下:1.前言2.硬阈值滤波原理介绍3.维纳滤波原理介绍4.BM3D原理详述1.前言图像去噪是计算机视觉前处理中很重要的一个环节,对于手机camera来讲,去噪的好坏直接影响最终图像的质量,图像…

    2022年6月7日
    56
  • 网格搜索法

    网格搜索法网格搜索法是指定参数值的一种穷举搜索方法 通过将估计函数的参数通过交叉验证的方法进行优化来得到最优的学习算法 即 将各个参数可能的取值进行排列组合 列出所有可能的组合结果生成 网格 然后将各组合用于 SVM 训练 并使用交叉验证对表现进行评估 在拟合函数尝试了所有的参数组合后 返回一个合适的分类器 自动调整至最佳参数组合 可以通过 clf best params 获得参数值 nbsp nbsp nbsp 版

    2026年3月26日
    1
  • fsync操作

    fsync操作/*update需要刷磁盘的操作*/#0os_file_fsync_posix(file=20)at/data/mysql-boost-5.7.32/mysql-5.7.32/storage/innobase/os/os0file.cc:3081#10x000000000198c562inos_file_flush_func(file=20)at/data/mysql-boost-5.7.32/mysql-5.7.32/storage/innobase/os/os0file.c

    2022年5月31日
    50
  • Manus被收购,智谱也定了8天后上市

    Manus被收购,智谱也定了8天后上市

    2026年3月12日
    2
  • Apache和Tomcat区别

    Apache和Tomcat区别nbsp nbsp 对比项 nbsp nbsp nbsp nbsp nbsp nbsp 服务器种类 nbsp 解释 java 程序 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 资源区别 Apache Web 服务器 不能 支持 html img 等静态资源 不支持动态请求如 CGI Servlet JSP PHP ASP Tomcat Java 服务器 Servl

    2026年3月19日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号