-
打印圆周率小数点后n位:
解题思路:
对于圆周率的计算可以采用马青公式
π=16*arctan1/5-4*arctan1/239
当n=1时
π = 16 * (1/5) - 4* (1/239)
当n=2时
π = 16 * (1/5- 1/3*5*5*5 ) - 4* (1/239-1/3*239*239*239)
当n=3时
π = 16 * (1/5- 1/3*5*5+1/5*(5的5次方) ) - 4* (1/239-1/3*239*239*239+1/5*(239的5次方))
此处可以用循环解决
下面要确定的就是循环的次数:
马青公式有这样一条结论:
-
-
每多计算一次,π的精确加2*log105 =1.39位
-
当要求小数位为n时:
通过以上公式反解所需次数为:n/(2*log105)
如此便可以计算π小数点后n位了
但是还有一点需要注意的是:题目中要求不能用到浮点型数据
这一点我们可以通过放大缩小的方法来解决
即 把π 放大n+10位(其中的10为计算磨损,后期会丢弃):相当于π乘以10的(n+10)次方 ,取整,得到的数据记为sum1
如此便可不用涉及到浮点数的计算
然后sum1再除以10的(10)次方
最后sum1还剩n+1位
其中从左到右第一位为3,剩下n为即为小数点的后n位
最后打印出来即可
下面是Python代码:
from __future__ import division
import time
import math
#处理数据格式异常
while True:
try:
number = int(input('请输入想要打印小数点后的位数n:'))
break
except ValueError:
print("请输入大于等于0的整数")
# 计算当前时间
time1 = time.time()
# 多计算10位,防止位数取舍影响
number1 = number + 10
# 根据马斯公式,每计算一次,精度增加2*log5(10)位
# 反解,若要是精度为number1位
# 需要计算的次数位 为:number1/(2*log5(10))
ma = int( ( number/(2*math.log(5, 10)) ))+1
ma1 = int( ( number1/(2*math.log(5, 10)) ))+1
# 由于是打印小数点位数,可以先扩大10**number1位
# 再缩小10**10位,这个为我们之前加入的误差
# π/4=4arctan1/5-arctan1/239
#一位精度时
x1 = 10**number1*16//5
x2 = 10**number1*4//-239
sum1 = x1 + x2
# 循环ma1次
for i in range(3, ma1*2,2):
x1 //= -5*5
x2 //= -239*239
sum1 += (x1+x2)//i
sum1 //= 10**10
result = str(sum1)
result = result[0]+"."+result[1:len(result)]
sw = {".":"点","1":"一","2":"二","3":"三","4":"四","5":"五","6":"六","7":"七","8":"八","9":"九","0":"零",}
s2 =""
# 将数字转换成汉字
for s in result:
s2=s2+sw.get(s)
print(f"sum为:{result[0]}{result[1:len(result)]}")
print(f"sum为:{s2}")
time2 = time.time()
print(f"耗时:{time2-time1}")