您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

一文帮你读懂Java浮点数的存储原理

时间:2019-10-18 14:39:36  来源:  作者:

前言

JAVA数值分整数和浮点数,前一篇文章已经解析了Java整数的存储原理,本篇将接着解析浮点数在计算机里的存储原理。Java浮点数分单精度类型( float)和双精度类型(double),float 数据占用 32bit,double 数据占用 64bit。

Java浮点数标准

java中浮点数采用的IEEE754标准,该标准的全称为IEEE二进制浮点数算术标准。这个标准规定的存储格式是这样的:符号位+指数位偏移+尾数位

 

一文帮你读懂Java浮点数的存储原理

 

 

IEEE 754常用的两种表示浮点数值的方式:单精确度(float 32位)、双精确度(double 64位)

一文帮你读懂Java浮点数的存储原理

 

 

  • 浮点数表示的数值:V = (-1)^s × M × 2^E
  • 符号(sign) :1个bit表示,当s=0,V为正数;当s=1,V为负数。
  • 阶码(exponent) :E的作用是对浮点数加权,用于存储科学计数法中的指数数据,并且采用移位存储。float类型的阶码是 8 bits,double类型的阶码是 11 bits。
  • 尾数(significand) :M是一个二进制小数,因为是二进制,所以科学计数法中这个值范围是:1≤M<2。(和十进制中范围为1~10一样)

IEEE 754对有效数字M和指数E,还有一些特别规定。前面说过,1≤M<2,也就是说,M可以写成1.xxxxxx的形式,其中xxxxxx表示小数部分。IEEE 754规定,在计算机内部保存 M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位float浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。 道理就是在这里,那 24bit 能精确到小数点后几位呢,我们知道 9 的二进制表示为 1001,所以 4bit 能精确十进制中的 1 位小数点, 24bit 就能使 float 能精确到小数点后 6 位

至于指数E,情况就比较复杂。 首先,E为一个无符号整数(unsigned int)这意味着,如果E为8位 (float类型) ,它的取值范围为0~255;如果E为11位(double类型),它的取值范围 为0~2047。但是,我们知道,科学计数法中的E是可以出现负数的(因为0.75用科学计数法表示就是1.1*2^-1),所以 IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

浮点数转二进制数

能精确表示的浮点数

哪些小数能被精确表示呢?0.5的倍数,且在精度以内。

方便计算,首先选择可以用浮点数精确表示的数计算:4.25

  • step1.首先将数字转为2进制:

整数部分4: "除2取余"

4/2=2 余 0

2/2=1 余 0

1/2=0 余 1

小数部分0.25:"乘2取整"

0.25 * 2 = 0.5 未进位 0

0.50 * 2 = 1 进位整数 1

二进制表示:100.01

  • step2.将二进制数转为科学计数法表示

科学记数法表示:1.0001 * 2^2

  • step3.转换为IEEE754格式存储

符号位 0 (正数0 负数1)

指数 2 (float指数+127=127 double指数+1023=1025)

尾数 0001

单精度float:符号位0 指数位129(10000001) 尾数001

0 10000001 00010000000000000000000

双精度double:符号位0 指数位1025(10000000001) 尾数001

0 10000000001 0001000000000000000000000000000000000000000000000000

不能精确表示的浮点数

举个例子:1/3,十进制就无法精确表示三分之一这个数字。

二进制也有很多很多小数无法精确表示,包括:0.1和0.2,这也是导致计算出现精度问题的根本原因。

下面将0.1转为2进制表示。

0.1

  • step1.首先将数字转为2进制:

0.10 * 2 = 0.20 未进位 0

0.20 * 2 = 0.40 未进位 0

0.40 * 2 = 0.80 未进位 0

0.80 * 2 = 1.60 进位 1

0.60 * 2 = 1.20 进位 1

0.20 * 2 = 0.40 未进位 0

0.40 * 2 = 0.80 未进位 0

0.80 * 2 = 1.60 进位 1

0.60 * 2 = 1.20 进位 1

无限循环(0011)...

二进制表示0.1:

0.00011001100110011001100110011001100110011001100110011001...

  • step2.将二进制数转为科学计数法表示

科学记数表示:

1.1001100110011001100110011001100110011001100110011001... * 2^-4

  • step3.转换为IEEE754格式存储

符号位 0 (正数0 负数1)

指数 -4 (float指数+127 double指数+1023)

尾数 1001100110011001100110011001100110011001100110011001...

float 单精度浮点数,尾数只能存储23位,多余位数四舍五入:

0 01111011 10011001100110011001101

double 双精度浮点数,尾数只能存储52位,多余位数四舍五入:

0 01111111011 1001100110011001100110011001100110011001100110011010

结语

本文详细解读了Java浮点数(包括单精度和双精度)在计算机中的存储原理,并且采用示例讲解了浮点数转换成二进制的方法,希望大家看完本篇后能够弄清楚浮点数是怎么在计算机中存储的。



Tags:Java浮点数   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
前言Java数值分整数和浮点数,前一篇文章已经解析了Java整数的存储原理,本篇将接着解析浮点数在计算机里的存储原理。Java浮点数分单精度类型( float)和双精度类型(double),float...【详细内容】
2019-10-18  Tags: Java浮点数  点击:(181)  评论:(0)  加入收藏
▌简易百科推荐
面向对象的特征之一封装 面向对象的特征之二继承 方法重写(override/overWrite) 方法的重载(overload)和重写(override)的区别: 面向对象特征之三:多态 Instanceof关键字...【详细内容】
2021-12-28  顶顶架构师    Tags:面向对象   点击:(2)  评论:(0)  加入收藏
一、Redis使用过程中一些小的注意点1、不要把Redis当成数据库来使用二、Arrays.asList常见失误需求:把数组转成list集合去处理。方法:Arrays.asList 或者 Java8的stream流式处...【详细内容】
2021-12-27  CF07    Tags:Java   点击:(3)  评论:(0)  加入收藏
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Java架构师之路    Tags:JAVA   点击:(5)  评论:(0)  加入收藏
大家好!我是老码农,一个喜欢技术、爱分享的同学,从今天开始和大家持续分享JVM调优方面的经验。JVM调优是个大话题,涉及的知识点很庞大 Java内存模型 垃圾回收机制 各种工具使用 ...【详细内容】
2021-12-23  小码匠和老码农    Tags:JVM调优   点击:(12)  评论:(0)  加入收藏
前言JDBC访问Postgresql的jsonb类型字段当然可以使用Postgresql jdbc驱动中提供的PGobject,但是这样在需要兼容多种数据库的系统开发中显得不那么通用,需要特殊处理。本文介绍...【详细内容】
2021-12-23  dingle    Tags:JDBC   点击:(13)  评论:(0)  加入收藏
Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的...【详细内容】
2021-12-23  JAVA小白    Tags:Java   点击:(11)  评论:(0)  加入收藏
Java从版本5开始,在 java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可...【详细内容】
2021-12-17  小西学JAVA    Tags:JAVA并发   点击:(11)  评论:(0)  加入收藏
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  唯一浩哥    Tags:Java基础   点击:(17)  评论:(0)  加入收藏
1、问题描述关于java中的日志管理logback,去年写过关于logback介绍的文章,这次项目中又优化了下,记录下,希望能帮到需要的朋友。2、解决方案这次其实是碰到了一个问题,一般的情况...【详细内容】
2021-12-15  软件老王    Tags:logback   点击:(19)  评论:(0)  加入收藏
本篇文章我们以AtomicInteger为例子,主要讲解下CAS(Compare And Swap)功能是如何在AtomicInteger中使用的,以及提供CAS功能的Unsafe对象。我们先从一个例子开始吧。假设现在我们...【详细内容】
2021-12-14  小西学JAVA    Tags:JAVA   点击:(22)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条