实数表示

float和double为什么能表示的范围大?为什么会失真

float能表示有效位数为6-7位,double有效位数为15-16位(负值取值范围为 -1.7976E+308 到 -4.94065645841246544E-324,正值取值范围为 4.94065645841246544E-324 到 1.797693E+308)。

float占4个字节,有32位:分别是符号位S(1位),指数位E(8位),尾数M(23位)。

比如123.6,写成二进制是10100101.0100=1.01001010100x2^7,存储过程:

  1. 首先符号位S,0表示正数,1表示负数。S=0

  2. 然后算出指数位E,这里指数为:e=7=0000 0111,根据IEEE754标准要求,E=e+127;即:E=7+127=134=1000 0110

  3. 再写出尾数M,即:M=0100 1010 1000 0000 0000 000

M(23位)最大可以表示7位数,因此float有效位为(精确到)7位,可以表示的负值取值范围为-2128~-2104,正值取值范围为2104~2108。double同理。

所以可以看到,虽然float和double可以表示的位数很大,但是牺牲了精确度

java如何比较float或double的大小:

  • 最常用:相减在某个范围内,如(double1-double2<=1e-6)
  • 转成字符串比较,但只适用于精度相同的
  • 使用sun提供的Double.doubleToLongBits()方法
  • 商业计算最好用BigDecimal。而且尽量用其字符串构造函数,比如BigDecimal("0.3")而不是BigDecimal(0.3)
posted @ 2021-04-23 23:08  i%2  阅读(105)  评论(0)    收藏  举报