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


    欢迎关注博主

    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指数小数部分
    0000
    非规约形式000大于0小于1
    规约形式1到 请添加图片描述[1,254][1,2046]大于等于1小于2
    无穷请添加图片描述25520450
    NaN请添加图片描述2552045非0

    参考资料:

    官方文档:数据类型

    官方文档:浮点数规范

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

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

  • 相关阅读:
    i.MX6ULL驱动开发 | 31 - Linux内核网络设备驱动框架
    uniApp开发小程序基础教程(一)
    Day 49 前端开发
    maven基础
    73.C++类模板
    计算机组成原理——第一章 计算机系统概论——复习逻辑图
    我的AI存储实践及思考
    【LeetCode热题100】--49.字母异位词分组
    python笔记二【string】
    苹果曝出两个 iOS 系统 0-Day 漏洞
  • 原文地址:https://blog.csdn.net/qq_38723677/article/details/125463159