Java float和double精度范围大小(二进制存储角度剖析)

简介: 要想理解float和double的取值范围和计算精度,必须先了解小数是如何在计算机中存储的:下面举例说明:如何将十进制数78.375转换成32位长的IEEE单精度格式。

Java float和double精度范围大小

要想理解float和double的取值范围和计算精度,必须先了解小数是如何在计算机中存储的:

下面举例说明:如何将十进制数78.375转换成32位长的IEEE单精度格式。

1. 小数的二进制转换(浮点数)

78.375的整数部分:请添加图片描述

小数部分:请添加图片描述

所以,78.375的二进制形式就是1001110.011

然后,使用二进制科学记数法,有:请添加图片描述

转换后用二进制科学记数法表示的这个数,有底有指数有小数部分,这个就叫做浮点数。

2. 二进制浮点数转小数

请添加图片描述

3. 浮点数在计算机中的存储

在计算机中,保存这个数使用的是浮点表示法,分为三大部分:

  • 第一部分用来存储符号位(sign),用来区分正负数,这里是0,表示正数
  • 第二部分用来存储指数(exponent),这里的指数是十进制的6
  • 第三部分用来存储小数(fraction),这里的小数部分是001110011

需要注意的是,指数也有正负之分。

请添加图片描述

比如float类型是32位,用浮点数表示法:

  • 符号位(sign)占用1位,用来表示正负数,指数位(exponent)占用8位,用来表示指数,小数位(fraction)占用23位,用来表示小数,不足位数补0。

而double类型是64位,用浮点数表示法:

  • 符号位(sign)占用1位,用来表示正负数,指数位(exponent)占用11位,用来表示指数,小数位(fraction)占用52位,用来表示小数,不足位数补0。

请添加图片描述

4. 指数位的偏移量与无符号表示(float偏移量是127,double偏移量是1023)

需要注意的是指数可能是负数,也有可能是正数,即指数是有符号整数,而有符号整数的计算是比无符号整数麻烦的。所以为了减少不必要的麻烦,在实际存储指数的时候,需要把指数转换成无符号整数。那么怎么转换呢?

意到float的指数部分是8位,则指数的取值范围是 -126到+127,为了消除负数带来的实际计算上的影响(比如比较大小,加减法等),可以在实际存储的时候,给指数做一个简单的映射,加上一个偏移量,比如float的指数偏移量为127,这样就不会有负数出现了。

  • 指数如果是6,则实际存储的是6+127=133,即把133转换为二进制之后再存储。
  • 指数如果是-3,则实际存储的是-3+127=124,即把124转换为二进制之后再存储。

当我们需要计算实际代表的十进制数的时候,再把指数减去偏移量即可。

对应的double类型,存储的时候指数偏移量是1023。

5. java中存储浮点数的方式

用float类型来保存十进制小数78.375的话,需要先转换成浮点数,得到符号位指数小数部分。然后转换为二进制,注意指数要偏移6+127=133。

请添加图片描述

6. IEEE754中的一些概念

在java规范中有说明:浮点数在概念上与IEEE二进制浮点算术标准ANSI/IEEE标准754-1985 (IEEE,纽约)中规定的单精度32位和双精度64位相关联。

归约浮点数:如果浮点数中指数部分的编码值在0<exponent<=(2^e)-2
之间,且在科学表示法的表示方式下,分数 (fraction) 部分最高有效位(即整数字)是1,那么这个浮点数将被称为规约形式的浮点数。“规约”是指用唯一确定的浮点形式去表示一个值。此处e指的是存储指数的比特的长度。

非规约浮点数:、如果浮点数的指数部分的编码值是0,分数部分非零,那么这个浮点数将被称为非规约形式的浮点数。一般是某个数字相当接近零时才会使用非规约型式来表示。 IEEE 754标准规定:非规约形式的浮点数的指数偏移值比规约形式的浮点数的指数偏移值小1。如float偏移量是127,则对应非规约浮点数偏移量是126。

7. float和double的范围到底是多少

Java中float占4个字节,32bit。计算范围公式为 S (2^(E-127))(1.M) ,其中S占一位是符号位,E所占8bit是指数位(E存储时偏移了127),M占23位是尾数位。

从IEEE754规范规约浮点数定义中我们了解到,对于float指数的范围是[1,254],所以float最大值:

请添加图片描述

即float取值范围是:请添加图片描述

double的最大值:

请添加图片描述

即double取值范围是:请添加图片描述

8. 特殊值

这里有三个特殊值需要指出:

  1. 如果指数是0并且尾数的小数部分是0,这个数±0(和符号位相关)
  2. 如果指数(2^e)-1并且尾数的小数部分是0,这个数是±∞)(同样和符号位相关)
  3. 如果指数(2^e)-1并且尾数的小数部分非0,这个数表示为非数NaN。

此处e指的是存储指数的比特的长度。

以上规则,总结如下:

形式 指数 float指数 double指数 小数部分
0 0 0 0
非规约形式 0 0 0 大于0小于1
规约形式 1到 请添加图片描述 [1,254] [1,2046] 大于等于1小于2
无穷 请添加图片描述 255 2045 0
NaN 请添加图片描述 255 2045 非0
参考资料:

官方文档:数据类型

官方文档:浮点数规范

80x86汇编语言与计算机体系结构(戴默)P14

维基百科:IEEE754二进制浮点数算法标准

目录
相关文章
|
2月前
|
存储 Java API
深入剖析Java Map:不只是存储数据,更是设计艺术的体现!
【10月更文挑战第17天】在Java编程中,Map是一种重要的数据结构,用于存储键值对,并展现了设计艺术的精髓。本文深入剖析了Map的设计原理和使用技巧,包括基本概念、设计艺术(如哈希表与红黑树的空间时间权衡)、以及使用技巧(如选择合适的实现类、避免空指针异常等),帮助读者更好地理解和应用Map。
105 3
|
2月前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
43 3
|
2月前
|
存储 Java
【编程基础知识】 分析学生成绩:用Java二维数组存储与输出
本文介绍如何使用Java二维数组存储和处理多个学生的各科成绩,包括成绩的输入、存储及格式化输出,适合初学者实践Java基础知识。
84 1
|
2天前
|
存储 Java
Java 11 的String是如何优化存储的?
本文介绍了Java中字符串存储优化的原理和实现。通过判断字符串是否全为拉丁字符,使用`byte`代替`char`存储,以节省空间。具体实现涉及`compress`和`toBytes`方法,前者用于尝试压缩字符串,后者则按常规方式存储。代码示例展示了如何根据配置决定使用哪种存储方式。
|
27天前
|
存储 缓存 安全
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见。本文介绍了使用 `File.createTempFile` 方法和自定义创建临时文件的两种方式,详细探讨了它们的使用场景和注意事项,包括数据缓存、文件上传下载和日志记录等。强调了清理临时文件、确保文件名唯一性和合理设置文件权限的重要性。
49 2
|
2月前
|
存储 C语言
使用 sizeof 操作符计算int, float, double 和 char四种变量字节大小
【10月更文挑战第13天】使用 sizeof 操作符计算int, float, double 和 char四种变量字节大小。
101 1
|
3月前
|
存储 Java
java数据结构,线性表链式存储(单链表)的实现
文章讲解了单链表的基本概念和Java实现,包括头指针、尾节点和节点结构。提供了实现代码,包括数据结构、接口定义和具体实现类。通过测试代码演示了单链表的基本操作,如添加、删除、更新和查找元素,并总结了操作的时间复杂度。
java数据结构,线性表链式存储(单链表)的实现
|
7月前
|
存储 Java
百度搜索:蓝易云【Java语言之float、double内存存储方式】
由于使用IEEE 754标准进行存储,float和double类型可以表示非常大或非常小的浮点数,并且具有一定的精度。然而,由于浮点数的特性,它们在进行精确计算时可能会存在舍入误差。在编写Java程序时,需要注意使
98 0
|
5月前
|
存储 编译器 C++
C++从遗忘到入门问题之float、double 和 long double 之间的主要区别是什么
C++从遗忘到入门问题之float、double 和 long double 之间的主要区别是什么
|
5月前
|
存储 SQL 数据库
MySQL设计规约问题之为何推荐用DECIMAL代替FLOAT和DOUBLE来存储精确浮点数
MySQL设计规约问题之为何推荐用DECIMAL代替FLOAT和DOUBLE来存储精确浮点数