将float类型1.0持续除以2至0会发生什么?32位精度下循环为何执行150次?
32位float循环执行150次的原因分析
先看这段代码:
float f = 1.0; while (f != 0.0) f = f / 2.0;
它在32位精度下执行150次才结束,不是单纯因为数值被舍入为0,核心原因要从32位float的存储结构和数值表示规则说起:
- 32位float的存储由三部分组成:1位符号位、8位指数位(偏移量为127)、23位尾数位。规格化数的指数范围是-126到+127,非规格化数用于表示接近0的极小值。
- 第一阶段(规格化数阶段):初始值
1.0对应的二进制是0 01111111 00000000000000000000000,指数为0(01111111 - 127 = 0)。每次执行f = f / 2.0,相当于指数减1。当指数从0降到-126时,一共执行了127次循环(0到-126共127个变化步长)。此时数值还能以规格化形式表示,尚未变为0。 - 第二阶段(非规格化数阶段):当指数再减1,就超出了规格化数的最小指数范围,此时进入非规格化模式——指数固定为-127,数值大小由尾数位决定。这时候每次除以2,相当于把尾数位右移一位,直到尾数位全为0。尾数位有23位,这一阶段会执行23次循环。
- 当尾数位全为0时,f的数值变为0.0,循环终止。127+23=150,正好是循环执行的总次数。
内容的提问来源于stack exchange,提问作者m_here
相关产品推荐
相关产品推荐

