《编程之美》学而思-精确表达浮点数
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表达分数
rational类存储整型的分子和分母,并且它们不可约。
若初始化时分母为零,则抛出一个异常;
若分数为负,则规定分子为负而分母为正;
若分子为0,则分母为1(即整数的分母均为1)。
计算机无法精确表示1/3,有理数类boost::rational可以,目的就是用来避免浮点数的精度损失问题
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可以,目的就是用来避免浮点数的精度损失问题
相关文章推荐
- PHP按符号截取字符串的指定部分
- PHP按符号截取字符串的指定部分
- PHP按符号截取字符串的指定部分
- Python笔记:protocol buffer使用
- java设计模式(1)-------单例,工厂,值对象,装饰模式
- eclipse调试(转)
- Java基础——反射(待续)
- struts2传递对象
- java之 ------ 设计思想
- 详解Python3中yield生成器的用法
- 使用Python3编写抓取网页和只抓网页图片的脚本
- 使用Python求解最大公约数的实现方法
- Python中列表和元组的相关语句和方法讲解
- Python3字符串学习教程
- Python中字典映射类型的学习教程
- 在类Unix系统上开始Python3编程入门
- 约瑟夫问题的Python和C++求解方法
- 关于python3中写入csv文件多余空行
- php输出前一天上周上月上季度
- PHP设计模式-策略模式