整数和浮点数转换时的精度损失
文章目录
- int和float转换时的精度损失
- float组成解析
- (1) 32位浮点数的结构
- (2)示例:解析一个浮点数
- (3)偏置值的作用
- (4) 偏置值为什么是127?
- (5)对比双精度浮点数(double)
- 精度损失
- (1)float→ int 的精度损失
- 原因:
- (2)int → float 的精度损失
- 同理的long和double
- (1)long
- (2)double
实线代表无信息丢失转换,虚线代表可能有精度损失的转换。

int和float转换时的精度损失
float组成解析
(1) 32位浮点数的结构
单精度浮点数(float
)占用 32位(4字节),按以下方式划分:
组成部分 | 位数 | 作用描述 |
---|---|---|
符号位(Sign) | 1 bit | 决定数值的正负:0 表示正数,1 表示负数。 |
阶码(Exponent) | 8 bit | 存储指数部分(需减去偏置值 127 得到实际指数)。 |
尾数(Mantissa) | 23 bit | 存储小数部分(隐含开头的 1. ,实际精度为24位)。 |
(2)示例:解析一个浮点数
假设32位二进制为:
0 10000010 01100000000000000000000
- 符号位:
0
→ 正数。 - 阶码:
10000010
(二进制) =130
(十进制) → 实际指数 =130 - 127 = 3
。 - 尾数:
01100000000000000000000
→ 隐含“1.”后为1.011
(二进制) =1 + 0.25 + 0.125 = 1.375
(十进制)。 - 最终值:+1.375×23=11.0+1.375×23=11.0。
(3)偏置值的作用
- 支持负指数:
- 若实际指数为
-3
,则存储为-3 + 127 = 124
(二进制01111100
)。 - 若实际指数为
5
,则存储为5 + 127 = 132
(二进制10000100
)。
- 若实际指数为
- 统一比较规则:
阶码作为无符号数时,直接比较大小即可判断指数的大小关系(无需处理符号位)。
(4) 偏置值为什么是127?
- 对于 8位阶码,可能的值范围是
0
~255
。 - 标准规定:
- 阶码范围
1
~254
:表示规格化数(实际指数-126
~+127
)。
(因为1 - 127 = -126
,254 - 127 = +127
)。这里包括0,且这里是指数0和下面的阶码0不一样。 - 阶码
0
:表示非规格化数(Denormalized Numbers)或零。 - 阶码
255
:表示无穷大(Infinity
)或非数值(NaN
)。
- 阶码范围
- 因此,偏置值
127
是 对称中心,使指数范围均衡覆盖正负值。
(5)对比双精度浮点数(double)
类型 | 总位数 | 符号位 | 阶码位数 | 尾数位数 | 偏置值 |
---|---|---|---|---|---|
float | 32 | 1 | 8 | 23 | 127 |
double | 64 | 1 | 11 | 52 | 1023 |
双精度(double
)提供更高的精度和更大的范围,但占用两倍内存。
精度损失
(1)float→ int 的精度损失
原因:
-
小数部分截断:
float
可能包含小数,而int
是纯整数,转换时小数部分直接被丢弃(不是四舍五入)。float f = 3.14f; int i = (int)f; // i = 3(丢失 0.14)
-
超出
int
范围:float
的表示范围(约 ±3.4×10³⁸)远大于int
(−2³¹ 到 2³¹−1),大数值转换会溢出。float f = 1e20f; int i = (int)f; // i = Integer.MAX_VALUE(溢出)
(2)int → float 的精度损失
尾数位数限制:float
只有 23 位有效尾数(实际精度约 6-7 位十进制数),若 int
的绝对值超过 223=8,388,608223=8,388,608,低位数字会被舍入。
int i = 16_777_717; // 二进制:1_00000000_00000000_00010101
float f = (float)i; // f = 16_777_720.0(最后3位被舍入)
同理的long和double
(1)long
-
存储格式:纯二进制补码形式,直接存储整数值。
-
组成:
部分 位数 说明 符号位 1 bit 0
表示正数,1
表示负数。数值位 63 bit 存储整数的绝对值,采用补码编码(负数取反加1)。
(2)double
-
存储格式:科学计数法的二进制形式,分为符号、阶码、尾数三部分。
-
组成:
部分 位数 说明 符号位(S) 1 bit 0
正数,1
负数。阶码(E) 11 bit 存储指数(实际指数 = E - 1023
,偏置值1023)。尾数(M) 52 bit 存储小数部分(隐含前导 1.
,实际尾数为1.M
)。