C/C++中如何让69.99*100输出6999而非6998?
问题根因
69.99属于十进制有限小数,但无法被二进制浮点数double精确存储,实际存储的数值略小于69.99。乘以100后得到的实际值为6998.999999999999左右,C/C++中将浮点数强转为int时会直接截断小数部分,因此最终得到6998而非预期的6999。
解决方案
- 方案1:运算后四舍五入再强转
引入<cmath>头文件的round()函数,对浮点运算结果做四舍五入后再转为整数,代码示例如下:#include <iostream> #include <cmath> using namespace std; int main() { double x = 69.99; int xi = static_cast<int>(round(x * 100)); cout << xi << endl; return 0; } - 方案2:金额类场景直接用整数存储最小单位
如果是处理金额、定价这类固定精度的业务,不要用浮点数存储数值,直接以最小单位(比如分)用整数存储,例如69.99元直接存为int x = 6999,需要展示为元的时候再除以100.0即可,从根源上避免浮点精度误差。 - 方案3:从字符串输入时直接解析为整数
如果数值是从字符串输入,不要先转成double再运算,直接按字符串拆分整数和小数部分,计算得到对应最小单位的整数值,例如解析"69.99"时,拆分出整数部分69、小数部分99,计算69*100 + 99直接得到6999,完全绕开浮点运算。 - 方案4:高精度场景使用十进制浮点类型
对精度要求极高、无法接受任何浮点误差的场景,可以使用专门的十进制运算库,或者C++20标准引入的std::decimal系列十进制浮点类型,避免二进制浮点数的固有精度问题。
内容的提问来源于stack exchange,提问作者tiplip
相关产品推荐
相关产品推荐

