您的位置:首页 > 编程语言

《编程之美》学而思-精确表达浮点数

2015-08-20 00:16 369 查看
《编程之美》学而思-精确表达浮点数

flyfish 2015-10-13

《编程之美》精确表达浮点数

有限小数或者无限循环小数都可以转化为分数。

有限小数:0.9 = 9/10 无限循环小数:0.333(3)= 1/3(括号中的数字表示是循环节)

1)对于有限小数:0.a1a2…an=(a1a2…an)/10n0.a_1a_2…a_n=(a_1a_2…a_n)/10^n

2)对于无限循环小数

X=0.a1a2…an(b1b2…bm)X=0.a_1a_2…a_n(b_1b_2…b_m)

10n∗X=a1a2…an.(b1b2…bm)10^n*X=a_1a_2…a_n.(b_1b_2…b_m)

10n∗X=a1a2…an+0.(b1b2…bm)10^n*X=a_1a_2…a_n+0.(b_1b_2…b_m)

X=(a1a2…an+0.(b1b2…bm))/10nX=(a_1a_2…a_n+0.(b_1b_2…b_m))/10^n

对于整数部分a1a2…ana_1a_2…a_n,不需要做额外处理,只需要把小数部分转化为分数形式再加上这个整数即可。对于后面的无限循环部分,可以采用如下方式进行处理:

那么

10m∗Y=b1b2…bm.(b1b2…bm)10^m*Y=b_1b_2…b_m.(b_1b_2…b_m) 10m∗Y=b1b2…bm+0.(b1b2…bm)10^m*Y=b_1b_2…b_m+0.(b_1b_2…b_m)

10m∗Y−Y=b1b2…bm10^m*Y-Y=b_1b_2…b_m

将Y代入前面的X的等式可得:

=(a1a2…an+b1b2…bm/(10m−1))/10n=(a_1a_2…a_n+b_1b_2…b_m/(10^m-1))/10^n

=((a1a2…an)∗(10m−1)+(b1b2…bm))/((10m−1)∗10n)=((a_1a_2…a_n)*(10^m-1)+(b_1b_2…b_m))/((10^m-1)*10^n)

例如,对于小数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可以,目的就是用来避免浮点数的精度损失问题
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: