计算任意位数的Pi
当用程序实现求pi的值时,也许你能够很快写出算法(利用求pi的几个公式),但是由于使用单变量保存结果,限于计算机硬件对变量的表示范围有限,因此,最多只能计算出pi值小数点后十多位。但需要得到一个更大位数的pi值时,就得考虑其他的算法。
我们采用这个公式计算pi: pi/2 = 1+1/3+1/3*2/5 + 1/3*2/5*3/7 + 1/3*2/5*3/7*4/9+......
在计算上述公式的个分式值时,由于1/3这类的分数是无限循环小数,而使用单变量时,由于变量能表示的范围有限,因此,多余的部分将被舍去。为了提高精度,这时可以定义数组来逐位保存无限循环小数,例如:定义有20个元素的数组temp,每个元素保存一位数,则2/3的结果讲师如下效果:
位0 位19
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
则
2/3 * 2/5
可按以下方式计算:
(1)由于2/3的结果以保存在数组temp中,用分数2/5的分子2去与数组temp的各个元素相乘,并将结果保存到temp个元素中。
(2)对数组temp个元素进行进位处理。
(3)用数组temp个元素除以分母5,并将结果保存到对应的数组元素中。在使用数组temp中的元素进行除法运算时,将从数组的低位(序号0)开始。首先用temp[0]的值除以5,列出其除法竖式如下:
1
5 [ 6
5
1
得到的商为1,则将商保存在数组temp[0]中,接着将余数1乘以10累加到下一个元素temp[1]中,使temp[1]的值变为16.用temp[1]的值16除以5,得到商为3,将商保存到temp[1]中,余数为1,将其乘以10累加到下一个元素temp[1]中,......,这样不断地重复,最后使temp数组变为如下形式:
位0 位19
1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
(4)通过上面的操作,完成了一个数列的计算,并按位保存到数组temp中,再将temp数组中的值累加到pi数组中。
不断重复上述过程,即可得到指定位数的pi值。
提示:由于数列可以不断重复,什么时候终止循环哪?当数组temp中的值全为0,则表示已经没有余数需要处理;如果数组中的元素一直不为0,就需要设置另外的条件来终止循环,如规定循环处理的次数。
计算任意位数Pi值的程序代码:
#include <stdio.h>
/* function: 计算任意位数pi值
auther: ZhangYachao
blog:http://blog.csdn.net/u012027907
*/
void CaculatePi()
{
int len,i; //len为小数长度
int numberator = 1,denominator = 3,result,carry;
int flag = 1,count = 0; //继续循环的标志及循环的次数
char *pi,*temp; //指向保存pi值和临时计算结果的数据
printf("请输入小数位数:");
scanf("%d",&len); len += 2; //增加两位
if(!(pi = (char*)malloc(sizeof(char)*len))) //分配保存pi值的内存
{
printf("分配内存失败!\n");
exit(0);
}
if(!(temp = (char*)malloc(sizeof(char)*len))) //分配保存呢临时值的内存
{
printf("分配内存失败!\n");
exit(0);
} for(i = 0; i < len; i++) //初始化数组
{
pi[i] = temp[i] = 0;
}
pi[1] = 2; //置初值
temp[1] = 2; while(flag && (++count < 2147483647)) //int的最大值 2147483647
{
carry = 0;
for(i = len-1; i > 0; i--) //从低位到高位相乘
{
result = temp[i] * numberator+carry; //用每一位去乘,再加上进位
temp[i] = result % 10; //保存个数
carry = result / 10; //进位
} carry = 0;
for(i = 0; i < len; i++) //有高位到低位进行除法运算
{
result = temp[i] + carry*10; //当前位加上前一位的余数
temp[i] = result / denominator; //当前位的整数部分
carry = result % denominator; //当前位的余数,累加到下一位的运算
}
flag = 0; //清除标志 for(i = len-1; i > 0; i--)
{
result = pi[i] + temp[i]; //将计算结果累加到result中
pi[i] = result % 10; //保留一位
pi[i-1] += result / 10; //向高位进位
flag |= temp[i]; //若temp中的数全为0,退出循环
}
numberator++; //累加分子
denominator += 2; //累加分母
}
printf("\n计算了%d次\n",count); //输出循环次数
printf("\t--- 第1-1000为小数----\n");
printf("PI = \n");
printf("%d.",pi[1]);
for(i = 2; i < len; i++)
{
if((i>2) && (i-2)%10 == 0) //每10位小数间加一个空格
printf(" ");
if((i>2) && (i-2)%50 == 0) //每50位小数换行
printf("\n"); printf("%d",(int)pi[i]); //输出一位小数
}
printf("\n"); }
void main()
{
CaculatePi();
}
运行结果:
参考《零基础学算法》
转载请标明出处:http://blog.csdn.net/u012027907
计算任意位数的Pi的更多相关文章
- Leetcode 357.计算各个位数不同的数字个数
计算各个位数不同的数字个数 给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 10n . 示例: 输入: 2 输出: 91 解释: 答案应为除去 11,22,33 ...
- MT2018笔试题之计算数字位数
一.计算数字位数 1.题目 给定一个数字T,计算从1到T的所有正整数的位数和.比如T=13,则12345678910111213有17位数字. 输入描述 3 13 4 5 输出 17 4 5 2.思路 ...
- day24 计算任意文件夹大小 , 校验大文件的一致性 , 发抢红包程序
#!/usr/bin/env python# -*- coding:utf-8 -*- # 1.计算任意一个文件夹的大小(考虑绝对路径的问题)# 基础需求 这个文件夹中只有文件# 进阶需求 这个文件夹 ...
- Shell 命令行,实现一个获取任意位数的随机密码的脚本
Shell 命令行,实现一个获取任意位数的随机密码的脚本 每次我们想要获得一个密码的时候都很头疼,于是我之前自己用nodejs写了一个 Shell 脚本.这两天在学习 bash Shell 所以,想用 ...
- js任意位数求和
<script> //任意位数求和 function sum(){ if(arguments.length==1) { console.log(arguments[0]) return; ...
- 一个js函数算出任意位数的水仙花数
一个算出任意位数的水仙花数的函数如下: var arr =[]; /*更改num确定取值范围*/ for(var num = 100; num <= 9999;num++){ /*多位数版本*/ ...
- Java实现 LeetCode 357 计算各个位数不同的数字个数
357. 计算各个位数不同的数字个数 给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 10n . 示例: 输入: 2 输出: 91 解释: 答案应为除去 11, ...
- leetcode 357. 计算各个位数不同的数字个数(DFS,回溯,数学)
题目链接 357. 计算各个位数不同的数字个数 题意: 给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 10n . 示例: 输入: 2 输出: 91 解释: 答 ...
- Python:raschii库计算任意阶数Stokes波
Stokes五阶波 最近发现一个很有用的Stokes波计算Python库,raschii官方说明,可以计算任意阶数,不同水深下的Stokes波,简单做了下测试,测试结果与脚本如下 Python 脚本 ...
随机推荐
- python3 读写excel
一直认为python3可以很快的实现很多简单的功能,今天要读excel表格数据,想来很简单,网上一搜,用xlrd即可,然后很多人给出了不同的版本,号称xlrd3,实际上官网一看,xlrd0.9.4兼容 ...
- 『重构--改善既有代码的设计』读书笔记----Move Method
明确函数所在类的位置是很重要的.这样可以避免你的类与别的类有太多耦合.也会让你的类的内聚性变得更加牢固,让你的整个系统变得更加整洁.简单来说,如果在你的程序中,某个类的函数在使用的过程中,更多的是在和 ...
- 我用Emacs,后来转向Vim——Vim学习之Vim键盘图(绝对值得珍藏)
Emacs本来就比较臃肿,麻烦.当我发现Vim键盘图时,我就渐渐转向Vim,追随Unix/Linux哲学去了.. 我用了Emacs三个月,因为它的学习曲线没Vim陡,这点吸引了,我使用Linux才7. ...
- html5 实现手机端相册浏览功能
原文地址:http://www.cootm.com/?p=710 在网上找到个浏览图片的jq插件,针对手机做的非常不错,看到乐享的微信微站新开发的功能就是这个,特此分享下! 时间匆忙,没做代码分析,勿 ...
- 你知道HTML标签设计的本意吗? 把HTML标签用到该用的地方去
"DIV+CSS"这个词汇不知道害了多少人,也许其提出者本意并没有错,但是跟风者从表现曲解了其意思,认为整个页面就应当是DIV+CSS文件的组合.这样做,对于视觉上并没有什么影响, ...
- Unity各平台路径总结
路径是Unity开发中令人头疼的一个问题,根据我的开发经验,现将开发中遇到的路径问题总结如下: 1. 如何读取Application.streamingAssetsPath下的文件? Edit.iOS ...
- BZOJ 1037 生日聚会
Description 今天是hidadz小朋友的生日,她邀请了许多朋友来参加她的生日party. hidadz带着朋友们来到花园中,打算坐成一排玩游戏.为了游戏不至于无聊,就座的方案应满足如下条件: ...
- 【Web Service】WSDL文档
WSDL文档仅仅是一个简单的XML文档. 它包含一系列描述某个web service的定义. WSDL WSDL 是基于 XML 的语言,用于描述 Web services 以及如何访问它们. WSD ...
- City Game
hdu1505:http://acm.hdu.edu.cn/showproblem.php?pid=1505 题解:给你一个字符矩阵,里面有R和F两种字符,然后让你找一个最大的子矩阵,这个最大的子矩阵 ...
- Ultra-QuickSort (poj 2002)
Description In this problem, you have to analyze a particular sorting algorithm. The algorithm proce ...