《编程之美》学而思-精确表达浮点数
flyfish 2015-10-13
《编程之美》精确表达浮点数
有限小数或者无限循环小数都可以转化为分数。
有限小数:0.9 = 9/10 无限循环小数:0.333(3)= 1/3(括号中的数字表示是循环节)
1)对于有限小数: 0.a1a2…an=(a1a2…an)/10n
2)对于无限循环小数
X=0.a1a2…an(b1b2…bm)
10n∗X=a1a2…an.(b1b2…bm)
10n∗X=a1a2…an+0.(b1b2…bm)
X=(a1a2…an+0.(b1b2…bm))/10n
对于整数部分 a1a2…an ,不需要做额外处理,只需要把小数部分转化为分数形式再加上这个整数即可。对于后面的无限循环部分,可以采用如下方式进行处理:
那么
10m∗Y=b1b2…bm.(b1b2…bm) 10m∗Y=b1b2…bm+0.(b1b2…bm)
10m∗Y−Y=b1b2…bm
将Y代入前面的X的等式可得:
=(a1a2…an+b1b2…bm/(10m−1))/10n
=((a1a2…an)∗(10m−1)+(b1b2…bm))/((10m−1)∗10n)
例如,对于小数0.3(33),根据上述方法,可以转化为分数:
0.3(33)
=(3*(10^2-1)+33)/((10^2-1)*10)
=(3*99+33)/990
=1/3 对于小数0.285714(285714),我们也可以算出:
0.285714(285714)
=(285714*(10^6-1)+285714)/((10^6-1)*10^6)
=(285714*999999+285714)/999999000000
=285714/999999
=2/7
Boost库中使用rational表达分数
#include <boost/rational.hpp>
boost::rational<int> a( 4, 3 ); // 4/3
boost::rational<int> b( 1, 2 ); // 1/2
boost::rational<int> c = a + b; // 4/3 + 1/2 = 11/6
a.numberator();//分子
a.denominator();//分母
double d = boost::rational_cast<double>( a );
rational类存储整型的分子和分母,并且它们不可约。
若初始化时分母为零,则抛出一个异常;
若分数为负,则规定分子为负而分母为正;
若分子为0,则分母为1(即整数的分母均为1)。
计算机无法精确表示1/3,有理数类boost::rational可以,目的就是用来避免浮点数的精度损失问题