为何使用fpm定点库计算的结果精度低于浮点数直接相乘?
问题解答
你没有操作错误,这是fixed_16_16定点类型的精度限制导致的正常现象,具体原因如下:
定点数的精度特性
fpm::fixed_16_16是16位整数部分 + 16位小数部分的定点数,它的小数部分只能以1/65536(即2^-16)为最小步长来表示数值。而2.2这个十进制小数无法被该步长精确拆解,会被近似为最接近的定点值:
- 0.2转换为16位小数的定点表示时,计算得
0.2 * 65536 = 13107.2,最终会被取整为13107或13108,对应定点值为2 + 13107/65536 = 2.199981689453125或2 + 13108/65536 = 2.20001220703125。 - 当这个近似值乘以2后,结果为
4.39996337890625或4.4000244140625,输出时因格式化截断/四舍五入显示为4.3999。
原生浮点数的对比
原生double类型的精度远高于16位小数的定点数(double有53位有效二进制位),虽然2.2同样无法被二进制浮点数精确表示,但它的近似值更接近真实的2.2,乘以2后的结果在默认输出格式化下会被显示为4.4。
解决建议
如果需要更高的精度来减少这类近似误差,可以使用小数位更多的定点类型,比如fpm::fixed_16_32(16位整数+32位小数),其最小步长为1/4294967296,能更精确地逼近像2.2这样的十进制小数。
原问题代码
#include <fpm/fixed.hpp> #include <fpm/ios.hpp> #include <iostream> int main() { fpm::fixed_16_16 x{2.2}; fpm::fixed_16_16 y{ 2 }; std::cout << (x * y) << std::endl; std::cout << (2.2 * 2) << std::endl; }
原输出结果
4.3999 4.4
内容的提问来源于stack exchange,提问作者intrigued_66
相关产品推荐
相关产品推荐

