java浮点数按ieee 754标准以二进制科学计数法存储,由符号位、指数位(float 8位/bias127,double 11位/bias1023)和隐含前导1的尾数位(float 23位,double 52位)构成;十进制小数如0.1在二进制中无限循环,截断导致精度丢失,故0.1+0.2≠0.3;比较需用误差容忍,金融计算须用bigdecimal。

Java 中的浮点型数据(float 和 double)不是简单地“存小数”,而是严格按 IEEE 754 标准以二进制科学计数法编码存储的。理解这个结构,才能明白为什么 0.1 + 0.2 ≠ 0.3、为什么不能用 == 比较,以及为什么金融计算要避开它们。
float 和 double 的内存布局完全一致,只是位宽不同
两者都拆成三部分:
- 符号位(1 bit):最高位,0 表示正,1 表示负;
- 指数位:float 占 8 位(偏移量 Bias = 127),double 占 11 位(Bias = 1023);实际指数 = 存储值 − Bias;
- 尾数位(Fraction):float 23 位,double 52 位;不存整数位的 1,只存小数点后的“.xxx”部分(隐含前导 1,叫规格化表示)。
例如 float 32 位排列是:1 位符号|8 位指数|23 位尾数;double 是:1 位符号|11 位指数|52 位尾数。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
十进制小数转二进制时就已产生误差
很多常见小数(如 0.1、0.2、0.6)在二进制中是无限循环小数:
- 0.1₁₀ = 0.0001100110011…₂(循环节 0011);
- float 只能保留前 23 位尾数,必须截断或舍入 → 得到近似值;
- double 虽有 52 位,仍无法终止该循环 → 还是近似值;
- 两个近似值相加,误差叠加,结果就是 0.30000000000000004。
赋值和比较必须注意精度陷阱
Java 默认把带小数点的字面量当作 double 类型,写 float 必须加后缀 f/F:
- 正确写法:
float f = 0.618f;,double d = 3.1415926;; - 错误写法:
float f = 0.618;(编译报错,类型不匹配); - 比较两个浮点数不能用 ==,应改用误差容忍判断:
Math.abs(a - b) ; - 需要精确计算(如金额)时,必须用
BigDecimal,而不是 float/double。
float 和 double 的典型使用场景
- double 是 Java 默认浮点类型,64 位,约 15 位有效数字,适合绝大多数科学计算、物理模拟等;
- float 32 位,约 6–7 位有效数字,内存占用小,在嵌入式、图形渲染(如 OpenGL)、对性能/内存敏感的场景仍有价值;
- 二者都不适用于金融、账务、精确计数等要求无舍入误差的领域。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










