ESP32中C语言整数乘除精度丢失原因及精准实现方案咨询
整数运算精度差异原因及解决方案
精度差异的核心原因
- 你在C代码中执行的是整数运算,C语言里整数除法会直接丢弃小数部分,只保留整数商,每一步的精度损失会不断累积,最终结果和浮点运算逻辑下的计算器结果完全不同。
- 拆解你的运算步骤(每一步均为整数运算):
150 × 10000 = 1500000(无精度损失)1500000 ÷ 155 = 9677(实际精确值约9677.419,小数部分被丢弃)9677 ÷ 138 = 70(实际精确值约70.123,小数部分被丢弃)70 × 100 = 7000(无损失)7000 ÷ 220 = 31(实际精确值约31.818,小数部分被丢弃)31 × 100 = 3100(最终结果)
- 手机/电脑计算器采用浮点运算,每一步都保留小数部分,能计算出完整的精确值,因此和整数运算结果存在明显差异。即使你把整数运算结果存入float变量,也只是将3100转换为浮点形式,之前步骤损失的精度无法恢复。
32位单片机上获取精确结果的方法
完全可以在ESP32这类32位单片机上得到和PC计算器一致的结果,只需调整运算方式:
- 改用浮点运算:将表达式中至少一个常量改为浮点类型(比如
150.0),让整个表达式自动按浮点规则计算,每一步保留小数部分。示例代码:
ESP32支持硬件浮点运算,这种方式效率足够,得到的结果会和计算器一致。float result = 150.0 * 10000 / 155 / 138 * 100 / 220 * 100; - 先乘后除+64位整数过渡:如果担心浮点运算的微小误差,可先将所有乘法用64位整数完成(避免32位整数溢出),再转浮点做除法。示例代码:
这种方式能最大程度减少中间步骤的精度损失,结果精度和计算器完全匹配。uint64_t total_mult = (uint64_t)150 * 10000 * 100 * 100; double result = (double)total_mult / 155 / 138 / 220;
内容的提问来源于stack exchange,提问作者Mario Christov
相关产品推荐
相关产品推荐

