对任意小数转化为分数的方法
mathcad吧
全部回复
仅看楼主
level 12
朱老剑客 楼主
刚才在一个网站上看到一个软件,可以将任意小数转化为分数,功能强不强且不说,它是收费的,$9.95,差不多60块钱人民币呢!其实用MC实现这个功能也不难。
我编这个程序差不多用了30min,包括发现了x-trunc(x)计算错误而重新编的时间,嗯,也就是说用MC半个小时能够赚约10美元,1天8小时的话,就是160美元,一个月干20天,月收入就是3200美元,基本上就是美国低收入群体的月薪吧,合人民币19200元,差不多算是北京一般白领的收入。还成吧……我本是想通过这个例子挤入美国高收入群体的……
2014年08月27日 13点08分 1
level 12
朱老剑客 楼主
嗯,这个程序仅对15位有效数字的输入可行,多了MC就不认了。出在num2str那句上,我们输入的只要是个数,就会收到MC的计算精度的限制。
而且我还发现一个奇怪的情况,恐怕是MC的bug,不知道MP会怎么样。@qiuletian这么处理的时候,得到的小数点后面的数跟乱码差不多了…… :(
2014年08月27日 14点08分 2
这是受到MC计算长度为17位的限制所产生误差,我试了一下,即使将零阀值调整为307都不行。
2014年08月28日 01点08分
肯定也受软件自身精度影响。(所有计算机软件,涉及数值计算时都有个精度限制:防止无限循环)。要绕开这个设定,比较费时费力。
2014年08月28日 02点08分
level 15
2014年08月27日 18点08分 3
最后的frac数组很有意思哈,像是给出了分子、分母的“生长型”,如果做成图的话就会比较明显了吧,若能够对“生长型”拟合出一个公式(或两个,分子一个,分母一个,或者“生长型”与小数之间有什么关系),或许会有一些新的有意思的发现了(比如说得到“小数转化为分数”的计算公式)。[呵呵]
2014年08月27日 22点08分
那是连分数形成的渐进分数。我曾经用C语言编过一个程序,等我把它改写成MC再上传。时间太晚,要睡觉,作业没做完。
2014年08月28日 00点08分
笔误:渐“进”分数,应为渐“近”分数。
2014年08月28日 00点08分
level 13
[哈哈][哈哈]
2014年08月28日 00点08分 4
level 13
将整数部分缩小为2位都不行
2014年08月28日 01点08分 5
level 13
一般来说,小数化为分数时有三种情形:
1、有限小数化为分数——这个剑客已经解决;
2、无限循环小数化为分数——有待解决;
3、无限不循环小数化为近似分数——有待解决。
比如对于π化为分数,在MC中有这样的结果
精度为1——15位
2014年08月28日 01点08分 6
提供思路: 第一个不说。第二个需要求极限。第三个,可以截取前N位成为有限小数。(悄悄的说一下:第三种叫无理数[呵呵]
2014年08月28日 02点08分
数学上有“无限”的概念,但是到了电脑中,都成了“有限”的,不能超过17位。所以,在电脑中处理的都是“有限”小数。
2014年08月29日 03点08分
level 12
朱老剑客 楼主
嗯,我到PTC论坛去问这个问题,他们说MC用的是双精度浮点数进行数值计算的,如果要进行高精度的计算,或者是使用专业的数论计算软件,或者是在MC中来编写矩阵和字符串的处理程序(这个程序就比较复杂了)。
我记得zpz老师给出过一个计算任意精度π的程序,算法有些莫名其妙,也是用矩阵(数组)来算的,通过矩阵的不断扩大延伸,得到相应位数的π的那个数字。
至于trunc()为啥会返回乱码一样的数字,PTC那边也没说出个子丑寅卯。
2014年08月28日 01点08分 7
早年俄语规定学,如今英语太蹩脚,提供算法原文件,任君研究或阅读。 链接:http://c9.yunpan.360.cn/my#texthttp://forum.simwe.com/thread-1111620-1-1.html
2014年09月01日 08点09分
level 13
e和根号2
验证了一些数字,没有明白它是怎么处理的——不是简单的不足近似,也不是过剩近似,还不是末尾加循环——也许用了什么算法,我不知道。
希望MC吧的吧友能指点一下。
2014年08月28日 02点08分 8
level 12
朱老剑客 楼主
这个吧,估计得看相关的数学教科书或者数论文献了。我猜zpz老师一定知道。@100zpz
2014年08月28日 03点08分 9
早年俄语规定学,如今英语太蹩脚,提供算法原文件,任君研究或阅读。 链接:http://c9.yunpan.360.cn/my#texthttp://forum.simwe.com/thread-1111620-1-1.html
2014年09月01日 08点09分
level 15
[无效] http://pan.baidu.com/s/1i3gh39r
小数化成分数,用连分数法,比较简便。它可以得到一连串的渐近分数,可以根据自己的需要和精度挑选其中的结果。这些分数已是分子和分母互质的最简分数,无须再行化简。
小数化成分数不仅有趣,而且有实际用途,比如齿轮的传动比要通过齿数固定的多个齿轮组合来实现,这就牵涉到小数(传动比)化成分数(齿数)的问题。
但是,我一直没有见到“正规”的算法介绍。用连分数法,是我学习连分数时,自己悟到的。如果,还有其他人使用此法,那正好证明科学的一致性。多年来,我用C、Word、Excel都编过这个程序。却没有MC。其中,法2,循环算法,是我一直使用的方法。法1是昨晚临时拼凑的,法3,递归法,是今天现编的。可能还有错误。请不要迷信计算结果,另行再验算一下。
连分数算法,算法思路有些不大好转弯。加上递归,容易把人“绕”进去。如果,有吧友看不懂,我再解释。
谢谢诸位。
2014年08月28日 15点08分 10
连分数算法,可用于实数范围内的任何数,零、正、负数,小数,整数带小数,无理数,整数(除非玩玩,一般不会代入整数的),都可通行无阻。
2014年08月28日 15点08分
level 12
朱老剑客 楼主
谢谢月城分享哈!真没想到这回的抛砖引玉活动会这么成功哈。
我还引到一条大鱼,PTC论坛里的一个网友Michael H看到我对提高MC计算精度的苦恼之后,和我分享了一个可计算任意精度π值的MC程序,编得非常精彩!是他2013年在π节的那天在PTC发表的一个程序,在工作表中,他给出了100000位π的计算结果。
下载地址:
http://1000eb.com/yk4r
他的算法很值得玩味,就是通过用MC模拟手算过程,全是加减乘除。
打开debugger的方法:“工具”菜单→“调试”→“切换调试”
2014年08月28日 16点08分 11
谢谢!已下载,慢慢研究。
2014年08月29日 02点08分
level 12
朱老剑客 楼主
月城的工作表太棒了!尤其是那个递归的程序,若搞一个“MC花式编程大赛”,这个估计能中头奖。
LNS问的不清楚MC使用了什么算法,比较运算的结果,我感觉MC的内置算法用的就是连分式法。
我大概算了一下运行时间:
从上图可知:
除了MC内置算法外,循环法用的时间最少。
confrac法,因为MC调用符号计算,相当于是引用了外部程序的dll,尽管是安装在同一个根目录下,但调用dll需要走windows的dllkernel,定位注册表键值后,将程序调出计算,然后再重新定位注册表到MC的数值计算界面进行程序板的计算,给出结果,这里绕了一个弯儿,所以即便是内置算法,计算速度也是有些慢的。MC进行符号运算的其他运算也是在这里卡。它的最好成绩是0.075s,最差成绩是0.094s。
循环法,用for break组合,这要较while快,因为不用调用boolean计算的dll文件,也是少走了很多弯路。它的最佳成绩是0.046s,和MC的内置算法相当了!最差成绩是0.078s。
递归法,在返回嵌套函数值的时候,多次遇到if,因为在这个程序里使用了好几个递归,每个递归都要调用dllkernel一次,算起来就显得慢一些了。它的最好成绩和confrac法时间相同,最差成绩是0.101s。
MC内置算法,就是在结果上双击,在“数字格式”菜单里选分数,并给出精度级。
从上面的例子可以看出,MC的内置函数的精度级控制并不是很理想的,有好几个重复答案,而在月城文件中可以看出,在相应的精度级处是有另外的更好的答案的。
因为MC内置算法是用C语言编写的,相比MC的解释语言本身就运行快很多,但从这个结果中看,首先结果质量不如用MC编程的效果好,其次运算速度并没有明显优势。我感觉很有可能MC内置算法使用的也是递归法结构。
它的最好成绩是0.046s,最差成绩是0.047s,发挥比较稳定,这是编译语言的特点。
综上所述,就像原来zpz老师指出的,用MC自己编程序不但可拓展函数的功能,运算效果更好,而且运算速度不一定就比编译语言的慢。
非常感谢月城的这次出色的表演!
2014年08月29日 03点08分 12
而且,从月城的编程中还可以看到,用数值计算编程实现符号计算的功能,并不是完全不可能的。
2014年08月29日 03点08分
还是朱老师高明!我只是编程,至于它在系统内部是怎么运作的,我确实不清楚。
2014年08月29日 03点08分
level 15
法2中的fval←0要删去,从其它程序中改写到MC中时,漏删了的。
我觉得,这三个连分数的算法都用了“递推”而不是“递归”,所以应该改称递“推”法。不知我这这个看法是否正确?
朱老师所说的MC内置法是什么?“格式”-“结果”-“数字格式”-“分数”?
2014年08月29日 03点08分 13
嗯,正是。
2014年08月29日 03点08分
level 12
朱老剑客 楼主
我原来在对微分进行逼近的时候用过confrac,效果跟泰勒展开差不多。
不过用confrac控制精度更直观一些,而且可以直接处理标量,而series需要将标量放在一个表达式里,然后在表达式里再想办法还原这个标量。比如说e,直接confrac,fraction就可以了,可在series中,需要写成e^x,然后series,x=1,才可以。
这次才发现连分式还可以用在对实数进行分数近似上。从月城给出的程序,以及我从连分式的构造观察上,感觉MC的confrac算法是这样的:
1)将x截断,提出整数部分,放在前面,“+”
2)小数部分取倒数,保留分子是1,此时分母是一个大于1的小数
3)对分母再反复进行1)、2),同时评价整个表达式值与原x之间的差ε,当ε小于给定误差值时,终止confrac。
而对一个实数进行分数逼近,等于是将我们所需要的逼近误差ε转化为我们所需要的连分式的层数,层数越多,逼近效果越好——这就是月城使用的办法。而MC的内置算法是将所选的层数换算成实数值,比较ε是否达到用户的要求,如果没有达到,则继续增加所选的层数,如果达到了就不再进行逼近了,所以MC的内置算法返回的值有一些是重复的——所以我认为MC的内置算法确实就是连分式逼近算法。
2014年08月29日 05点08分 15
level 15

MC的帮助中的“QuickSheet - 符号微积分”中,关于confrac有这样一段话:
"默认情况下,Mathcad 返回足够的连分式项,以使答案精确到 10 个有效位。要返回不同精确度的结果,在 "confrac" 后添加指定有效位数的正整数即可。"
试验了一下,结果并不令人满意。confrac不能穷尽连分数的部分商a(n),所以使用它,结果分数的值达不到满意的结果。建议使用法2或法3,而不要用法1。
法1:
法2:
法3:
2014年08月30日 03点08分 17
level 15
把法1弄丢了:
法1:
2014年08月30日 03点08分 18
level 15
连分数的渐近分数是从两个方向逼近准确值的,所以,在结果矩阵中可以看到误差值的正负号交替出现,也就是说,渐近分数的不足近似值和过剩近似值交替出现。
2014年08月30日 03点08分 19
level 15
e 的渐近分数:
2014年08月30日 04点08分 21
level 15
2014年08月30日 04点08分 23
level 11
一个程序比一个牛比,请求大牛们将这些程序上传到一个固定的网盘好吗?谢谢!
2014年08月30日 04点08分 24
见10楼第一行
2014年08月30日 05点08分
1 2 尾页