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

如何避免浮点格式错误?实现1.39×10000=13900的解决方案

搞定1.39×10000得到精确13900的问题

兄弟,这个坑我之前踩过!你说的完全对——像1.39这种十进制小数,根本没法用二进制浮点数精确存储,内存里它其实是个无限接近1.39的近似值。乘10000的时候,这点微小误差被放大,结果就不是精确的13900;而乘100000时刚好误差被抵消,凑出了正确值,这真的是巧合而已。

下面给你几个实用的解决办法,按需选择:

方法一:用十进制浮点类型(C++11及以上)

C++有专门处理十进制小数的类型,比如std::decimal::decimal32/decimal64,它们是按十进制规则存储的,能精确表示1.39这种数。不过要注意编译器支持(比如GCC需要开启相关编译选项),示例代码:

#include <decimal/decimal>
#include <iostream>

int main() {
    std::decimal::decimal64 num = 1.39DD;
    auto result = num * 10000;
    std::cout << static_cast<long long>(result) << std::endl; // 稳稳输出13900
    return 0;
}

方法二:用整数运算绕开浮点误差

既然1.39是两位小数,直接把它转成整数运算就行,完全避开浮点坑:

#include <iostream>

int main() {
    // 把1.39转成整数139(相当于×100)
    int num = 139;
    // 1.39×10000 = 139×(10000/100) = 139×100
    int result = num * 100;
    std::cout << result << std::endl; // 输出13900
    return 0;
}

如果是从字符串读取的1.39,直接解析成整数部分+小数部分的组合计算,会更稳妥。

方法三:四舍五入修正结果

如果必须用普通double类型,那计算后给结果做个四舍五入,把微小误差修正掉:

#include <iostream>
#include <cmath>

int main() {
    double num = 1.39;
    double result = num * 10000;
    // 用llround四舍五入到最近整数,比强制转int靠谱
    long long rounded_result = std::llround(result);
    std::cout << rounded_result << std::endl; // 输出13900
    return 0;
}

这里要提一句:强制类型转换只会截断小数部分,如果结果是13899.999999999998,强转int会得到13899,而llround会正确转成13900。

为啥乘100000能得到正确结果?

其实那也是假象!你可以试试用cout << std::setprecision(15) << (1.39 * 100000),会看到它其实是138999.99999999997之类的数值,只是cout默认输出时自动四舍五入成了整数139000而已。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:05:34