You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决float类型Machine Epsilon(机器精度)计算错误?

32位float机器精度计算结果异常排查

我尝试计算32位float类型的Machine Epsilon(机器精度),预期结果为已知的1.19e-07,但实际得到的是对应long double类型的1.08e-19。以下是我的代码:

#include <stdio.h>
void get_eps(float *eps) {
    *eps = 1.0f;

    while ((1.0f + *eps / 2.0f) != 1.0f) {
        *eps /= 2.0f;
    }
}

int main(){
    float eps;

    get_eps(&eps);
    printf("Machine Accuracy (get_eps): 	%.10g\n", eps);

    return 0;
}

问题根源

问题出在表达式的隐式类型提升:

  • 循环条件中,1.0f + *eps / 2.0f的运算结果会被编译器隐式提升为double类型(多数编译器默认会将float运算提升至double以获得更高精度),随后与同样被提升为double的1.0f进行比较。
  • 这导致循环实际判断的是double类型的精度阈值,而非float的。当*eps被不断除以2,直到小到double的机器精度级别(约1.08e-19)时,1.0 + (*eps/2.0)才会等于1.0,循环终止。

修复方案

强制让循环条件的运算全程保持在float类型范围内,两种可行方式:

方案1:显式强制转换运算结果

修改循环条件,将加法结果强制转换为float,避免隐式提升:

while ((float)(1.0f + *eps / 2.0f) != 1.0f) {
    *eps /= 2.0f;
}

方案2:用float临时变量存储中间结果

通过float类型的临时变量截断运算结果,确保比较在float精度下进行:

void get_eps(float *eps) {
    *eps = 1.0f;
    float sum;
    while ((sum = 1.0f + *eps / 2.0f) != 1.0f) {
        *eps /= 2.0f;
    }
}

验证结果

修改后运行代码,将得到预期的32位float机器精度值:1.19209290e-07。


内容的提问来源于stack exchange,提问作者Marc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 12:46:03