float double取值范围_double float区别

float double取值范围_double float区别Java浮点数浮点数结构  要说清楚Java浮点数的取值范围与其精度,必须先了解浮点数的表示方法,浮点数的结构组成,之所以会有这种所谓的结构,是因为机器只认识01,你想表示小数,你要机器认识小数点这个东西,必须采用某种方法,比如,简单点的,float四个字节,前两个字节表示整数位,后两个字节表示小数位(这就是一种规则标准),这样就组成一个浮点数。而Java中浮点数采用的是IEEE754标准。IEE

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

Java浮点数

浮点数结构

要说清楚Java浮点数的取值范围与其精度,必须先了解浮点数的表示方法,浮点数的结构组成,之所以会有这种所谓的结构,是因为机器只认识01,你想表示小数,你要机器认识小数点这个东西,必须采用某种方法,比如,简单点的,float四个字节,前两个字节表示整数位,后两个字节表示小数位(这就是一种规则标准),这样就组成一个浮点数。而Java中浮点数采用的是IEEE 754标准。

IEEE 754

这里就不细说什么是IEEE 754了,就直接讲具体内容,有兴趣的可以自己百度。

float

符号位(S):1bit 指数位(E):8bit 尾数位(M):23bit

一个float4字节32位,分为三部分:符号位,指数位,尾数位。

(1).符号位(S):最高位(31位)为符号位,表示整个浮点数的正负,0为正,1为负;

(2).指数位(E):23-30位共8位为指数位,这里指数的底数规定为2(取值范围:0-255)。这一部分的最终结果格式为: 2 E − 127 2^{E-127} 2E127,即范围-127~128。另外,标准中,还规定了,当指数位8位全0或全1的时候,浮点数为非正规形式(这个时候尾数不一样了),所以指数位真正范围为:-126~127。

(3).尾数位(M):0-22位共23位为尾数位,表示小数部分的尾数,即形式为1.M或0.M,至于什么时候是1,什么时候是0,则由指数和尾数共同决定(注意了,这个小数部分最高位并不在这32位里面,只是个隐含信息,由指数部分和尾数部分共同决定,说白了就是IEEE754这样规定的)。
小数部分最高有效位是1的数被称为正规(规格化)形式。小数部分最高有效位是0的数被称为非正规(非规格化)形式,其他情况是特殊值。
最终float的值 = ( − 1 ) S ∗ ( 2 E − 127 ) ∗ ( 1. M ) (-1)^S*(2^{E-127})*(1.M ) (1)S(2E127)(1.M)。具体形式如下:

符号

指数

部分

指数部分-127

尾数部分

小数部分的

最高有效位

形式

1

255

128

非0

没有

NaN

1

255

128

0

没有

负无穷

1

1~254

-126~127

任意

1

正规形式(负数)

1

0

-127

非0

0

非正规形式(负数)

1

0

-127

0

没有

负0

0

0

-127

0

没有

正0

0

0

-127

非0

0

非正规形式(正数)

0

1~254

-126~127

任意

1

正规形式(正数)

0

255

128

0

没有

正无穷

0

255

128

非0

没有

NaN

double

符号位(S):1bit 指数位(E):11bit 尾数位(M):52bit

double这里就类似float,只是double的长度更大,所以范围就更大,但规则是一样的。double的值 = ( − 1 ) S ∗ ( 2 E − 1023 ) ∗ ( 1. M ) (-1)^S*(2^{E-1023})*(1.M ) (1)S(2E1023)(1.M)

取值范围

根据表1可知,float的取值范围:
负无穷 —— − 2 128 -2^{128} 2128 ~~~ − 2 − 149 -2^{-149} 2149 —— 0 —— 2 − 149 2^{-149} 2149 ~~ 2 128 2^{128} 2128 —— 正无穷
1). 上面的“——”表示中间不能取值,例如负无穷到 − 2 128 -2^{128} 2128中间的值是取不到的(事实上128也是取不到的,只是接近近似值),但这并不是意味着,“~”任意值都能取到的,要注意,浮点数都是有精度的,并不能表示绝对值任意小的值。另外,Java中无穷大表示为:

Float.POSITIVE_INFINITY或Double.POSITIVE_INFINITY//表示正无穷大
Float.NEGATIVE_INFINITY或Double.NEGATIVE_INFINITY//负无穷大
//他们打印的结果:+/-Infinity
float f1 = (float)Math.pow(2,128);//指数>=128的,打印结果:Infinity
//上面要加(float)强制转换,否则编译提示出错,详细可参考前一节:Java变量数据类型
float f2 = (float)Math.pow(2,127);//1.7014118E38
System.out.println(Float.MAX_VALUE);//3.4028235E38
//其他测试,读者可自行测试

Jetbrains全家桶1年46,售后保障稳定

2). -149的得来:看上面理论应该是150(指数全0,则指数值 = 0 -127,这个时候尾数取最小, 2 − 23 2^{-23} 223,则-127-23 = -150),可不知道为什么是149,我查到的资料是说,全0,全1为特殊值,不作为范围内的值,上面的float的最大最小值Float.MAX_VALUE都是接近 2 128 2^{128} 2128)。故值 = ( − 1 ) S ∗ ( 2 − 126 ) ∗ ( 2 − 23 ) (-1)^S*(2^{-126})*(2^{-23}) (1)S(2126)(223) = +/- 2 − 149 2^{-149} 2149

float f3 = (float) Math.pow(2,-149)//1.4E-45,小于-149,结果则为0.0
Float.MIN_VALUE //1.4E-45

double的取值同float:
负无穷 —— − 2 1024 -2^{1024} 21024 ~~~ − 2 − 1074 -2^{-1074} 21074 —— 0 —— 2 − 1074 2^{-1074} 21074 ~~ 2 1024 2^{1024} 21024 —— 正无穷
1074 =| (-1022) – (52)|

另外,注意表格中,还有NaN,即表示非数值,例如:

System.out.println(0.0/0.0);//打印结果:NaN。注意不能是 0/0
//NaN表示计算错误,具体出现情况,可以参考表中
//Float.NaN或 Double.NaN 也能直接表示NaN,NaN与其他数计算结果均为NaN,除了
Math.pow(Float.NaN,0);//结果为1.0
//另外NaN == NaN; false

浮点数精度

精度是由尾数决定的,为什么?由浮点数的值计算公式可知:当指数的最终值为负,虽然这个时候浮点数的值能表示更小,但这个时候仅仅能表示0~1(或-1~0)这个数段的小数,没有实际意义。所以精度主要是看尾数的值。

float

float的尾数:23位,其范围为:0~ 2 23 2^{23} 223,而 2 23 = 8388608 = 1 0 6.92 2^{23}=8388608=10^{6.92} 223=8388608=106.92,所以float的精度为6~7位,能保证6位为绝对精确,7位一般也是正确的,8位就不一定了(但不是说8位就绝对不对了),注意这里的6~7位是有效小数位(大的数你先需要转换成小数的指数形式,例如:8317637.5,其有效小数位:8.3176375E6,七位),而有效位(从第一个不为0的开始数)是7~8位,是包括整数位的,像8317637.5,你不转换,则要从有效位的角度来看,有8位有效位。

System.out.println((float)Math.pow(10,6.92));//注意加float强制转换
//打印结果8317637.5,float只保证7~8位有效位,其余位数舍入

不理解的话,可以再这样想:23位,二进制0101……0101,尾数表示小数位,最小为0000……0001(22个0,最后一个1),即 2 − 23 2^{-23} 223=1.1920929E-7 ,这是float的最小单元(大概是0.0000001192大小,你想表示比这更小的,比如0.00000001,不可能啊),这是一个7位小数位小数,最小就是这么小,比这个更小的,计算机就无能为力了,比这个更大的,每次通过加这么一个最小单元,直到相等或接近(两个相差一个最小单元的数,它们之间的数也是不能表示的,所以有的7位也是不能精确的,因为最小不是0.0000001,而是比这个稍大)。

double

计算方式同float,double的尾数:52位, 2 − 52 2^{-52} 252=2.220446049250313E-16,最小是16位,但最小不是1.0E-16,所以精度是15~16,能保证15,一般16位。
  更多关于Java浮点数的,可以参考这里:基础野:细说浮点数(肥子John)

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

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/203718.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 基于LM331的电压-频率转换电路详细介绍[通俗易懂]

    基于LM331的电压-频率转换电路详细介绍[通俗易懂]目录1.LM331简介2.引脚分布与功能3.LM331的功能框图4.V/F转换的工作原理5.LM331的V/F转换电路1.LM331简介LM331是由美国NS公司(已被TI公司收购)生产的高精度频率-电压转换芯片,可以用于AD转换、频率-电压转换、电压-频率转换和转速测量等。当用作频率-电压转换时输出频率与输入电压成正比例关系,线性失真最大为0.01%。动态范围广,最大可达100dB;温度稳定性高,温度系数为±50ppm/℃;工作范围广(1Hz-100kHz);外.

  • C++_vector操作

    C++_vector操作vector说明:vector是向量类型,可以容纳许多类型的数据,因此也被称为容器(可以理解为动态数组,是封装好了的类)vector头文件-vectorvector初始化:方式1.vector<int>a(10);//定义具有10个整型元素的向量(尖括号为元素类型名,它可以是任何合法的数据类型),不具有初值,其值不确定方式2.vector<int>a…

  • 浅析AnyCast网络技术「建议收藏」

    浅析AnyCast网络技术「建议收藏」什么是BGPAnyCast?BGPanycast就是利用一个(多个)as号码在不同的地区广播相同的一个ip段。利用bgp的寻路原则,短的aspath会选成最优路径(bgp寻路原则之n),从而优化了访问速度。其实bgpanycast是不同服务器用了相同的ip地址。阿里的DNS就是使用了BGPAnyCast“其实bgpanycast是不同服务器用了相同的ip地址。”言简意赅啊!D…

  • 慧荣SM2246主控开卡一直处于Pretest状态解决方案

    慧荣SM2246主控开卡一直处于Pretest状态解决方案慧荣SM2246开卡;CH通道;CE使能

  • Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executing in

    Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executing in

  • 在Linux(Ubuntu版)下编写运行C语言程序

    在Linux(Ubuntu版)下编写运行C语言程序    最初学习C语言用的是VisualC++6.0,后来还用过一些IDE,复制粘贴都可以用鼠标对目标进行选择即可。但在Linux系统里,需要熟练掌握在Terminal里编写C语言程序,进行编译调试。本章主要介绍在Linux的终端下编写C程序并编译运行。一,编写C时需要掌握的一些Linux操作(1)文件管理相关的命令Linux命令名称作用使用举例mkdir新建文件夹mkdirtest,m…

发表回复

您的电子邮箱地址不会被公开。

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