本文附上我大二时自己写的源码,有很多不到位的地方请大家多多指教~
更多工程计算的源码请移步我上传的资源!都是19年上工程计算课的时候自己打的。
题目如图:
源程序如下:
function mypi(a) % a表示即将返回的π值的精度 a 为希望保留的小数点后位数
n=10000; %重复次数
m=0; %落在1/4圆内的次数 % 循环实验 半径为1 % pi*(1/2)^2:1^2=pi/4 1/4个圆
for i=1:n
x = rand;
y = rand;%随机生成y坐标
if sqrt(x^2 + y^2) < 1 % 落在1/4圆内
m = m + 1;
end
end
fprintf('当精度为%d时,计算出来的圆周率为:pi=%g\n',a,round((4 * m / n)*(10^a))/(10^a))
end
期间删删改改好多次,虽然始终无法做到老师说的 10行以内解决 的要求,但是还是勉强把程序做到了我能做到的最精简,并且尽量使其运行速度更快,从最开始的13秒多到了后来的7秒多,再到现在的9秒多。
虽然多了2秒多,但是最后输出的数结果是被控制了的,这个功能在7秒多的时候并没有被实现。
我的问题在于:无法在用 fprintf 输出字符串和数的同时用 %g %e %f %d中的任何一个实现控制精度的功能。(这四个语句的数字输出形式详见 ‘MATLAB正月点灯笼老师课程笔记:第一课:基础’ 的末尾)
后来的解决方法是:参照了网上众多大神们的意见方法后,我发现 用round函数可以间接控制精度:
虽然这样未免有点繁琐,但是为了实现功能,我尝试了一下:
a = 2;
round(1.235679845*(10^a))/(10^a)
ans =
1.2400
虽然有效数字保留到了小数点后两位,但是还是有0存在,现在的问题就变成了如何去掉这里的0:
但是这个问题并不难,只要使用%g,就可以很方便的去掉0了。
以上是我的收获1:输入精度并控制输出
收获2:
我发现用sqrt函数能大幅度的加快函数的运行速度!
之前的运行时间从13秒多到后来的7秒多就是这么来的,几乎整整加快了一倍!
源程序如下:
function mypi(a)
% a表示即将返回的π值的精度 a 为希望保留的小数点后位数
n=100000; %重复次数
m=0; %落在1/4圆内的次数 % 循环实验 半径为1 % pi*(1/2)^2:1^2=pi/4 1/4个圆
r = 0;
for i=1:n
x = rand;
y = rand;%随机生成y坐标
if sqrt(x^2 + y^2) < 1 % 落在1/4圆内
m = m + 1;
end
% disp(abs((4*m/n)-pi))
if abs((4*m/n)-pi) <= 1/10^a
r = r +1; end
end
if r >= 3
fprintf('当精度为%d时,计算出来的圆周率为:pi=%g\n',a,4 * m / n)
else fprintf('精度未达到要求!\n')
end
end
改进后的程序:
function mypi_jishu(a)
% 此方法可以保证至少三次绝对精度在要求范围内,且速度较快
% 输入a值需要为希望的小数点后位数(正整数)
n = 1000000;
y = 0;
m = 0;
for i = 1:n
xx = 1/i^2;
y = y+xx;
if abs((sqrt(6*y)-pi)/pi) < 10^(-a)
m = m+1;
end
end
if m >= 3
fprintf('当精度为%d时,计算出来的圆周率为:pi=%g\n',a,sqrt(6*y))
else
fprintf('精度未达到要求!\n')
end
end