技术问询:单精度浮点数首个碰撞数是否为131072.02及音频参数适配
关于单精度float首个两位尾数碰撞正数的判断
首先直接给结论:你声明的131072.02作为首个发生表示碰撞的两位尾数正数并不准确,实际首个触发碰撞的是131072.01——它和131072.02会被单精度float表示为同一个值。下面详细拆解原因:
单精度float的精度特性
单精度float采用1位符号位、8位指数位、23位尾数位的结构,隐含一个前导1,总共提供24位有效二进制精度,对应大约6-7位十进制有效数字。关键的一点是:随着数值增大,相邻两个float的间隔(称为ulp,Unit in the Last Place)会指数级增长。
对于形如2^n的数值,ulp的计算公式是:
ulp(2^n) = 2^(n - 23)
临界值计算
我们需要找到最小的正数,使得ulp≥0.01(因为两位尾数的数间隔是0.01,当ulp≥0.01时,就会出现不同的两位尾数被映射到同一个float的情况):
- 当
n=16(对应数值65536),ulp=2(16-23)=2-7=0.0078125 < 0.01。此时两位尾数的数(比如65536.01和65536.02)差值0.01大于ulp,它们的float表示不同,不会碰撞。 - 当
n=17(对应数值131072),ulp=2(17-23)=2-6=0.015625 ≥ 0.01。此时两位尾数的数差值0.01小于ulp,多个不同的两位尾数会被舍入到同一个float值。
首个碰撞的具体情况
- 131072.00是可以被float精确表示的(因为它是2的整数次幂)。
- 131072.01:小数部分0.01距离最近的ulp刻度(0和0.015625),0.01与0.015625的差(0.005625)更小,所以会被舍入到
131072.015625。 - 131072.02:小数部分0.02距离0.015625的差(0.004375)远小于距离下一个ulp刻度(0.03125)的差(0.01125),同样会被舍入到
131072.015625。
这意味着131072.01和131072.02是第一对发生表示碰撞的两位尾数正数,而非单独的131072.02作为首个碰撞数。
对你的音频应用的额外提示
你的频率范围是20.00Hz到22000.00Hz,这个区间远小于131072。以22000Hz为例,它对应的ulp约为0.00195,远小于0.01——这意味着你所需的所有两位尾数频率值,都可以被单精度float准确区分,不会发生表示碰撞,完全满足你的精度要求。
内容的提问来源于stack exchange,提问作者markzzz
相关产品推荐
相关产品推荐

