从计算机组成原理看浮点数取值范围

  • 一、浮点数在计算机中的存储
  • 二、java中float与double的表示范围与精度
  • 三、关于补码的补充


一、浮点数在计算机中的存储

浮点数的存储方案来源于IEEE 754标准。如何在只能存0和1的计算机中存储浮点数呢?关键是做到浮点数的三部分信息分别存储,包括正负号,尾数,和指数。
于是我们想到了科学计数法。但是我们常接触的科学计数法是类似于2*10^2这种,十进制的科学计数法,要想将浮点数表示为0或1,必须使用二进制的科学计数法,下面一张表格介绍一下二进制的科学计数法:

1

1

1

1

.

1

1

1

1

23

22

21

20

小数点

2-1

2-2

2-3

2-4

比如3.5=二进制11.1=21+20+2-1
科学计数法表示为:1.11*21
于是我们分离出三部分信息:S(正负号)E(尾数)M(指数)
常见浮点数分为两种:4字节(如java的float)浮点数,8字节(如java的double)浮点数;无论如何,第一位都要存正负号的,0正1负;指数占据8bit(4字节)或11bit(8字节);

  • 为了避免指数为负数,指数按补码存储,所以要添加偏移量,4字节8位偏移量127,8字节11位偏移量1023。
  • 尾数部分,由于小数点之前必然是1,所以只需存储小数点之后的部分即可。
  • 循环小数使用0舍1入处理
  • 大端存储与小端存储的区别:大端与阅读习惯一致

二、java中float与double的表示范围与精度

注意float的指数部分8位,最大值为01111111(首位是符号位),即127,所以最大值就是2127,最小值就是-2128,浮点数的表示范围按指数表示,所以float范围-2128-2127,就是java 为什么会有浮点数精度问题_开发语言 ~ java 为什么会有浮点数精度问题_java 为什么会有浮点数精度问题_02,同理,double范围-21024-21023,就是java 为什么会有浮点数精度问题_开发语言_03 ~ java 为什么会有浮点数精度问题_开发语言_04
而精度取决于尾数,float尾数范围是223 = 8388608,最多能有7位有效数字,绝对能保证的为6位,所以float的精度为6~7位有效数字;
double尾数的范围是252 = 4503599627370496,一共16位,精度为15~16位。

三、关于补码的补充

  • 0和正数的补码是本身,负数的补码是对应正数按位取反+1
    比如4位,1111补码就是1001,实际上就是负数补码与对应正数(补码)和为0,其中第一位表示符号
  • 补码-0就是最小值(8位:-2128),+0就是0值