黑马程序员技术交流社区
标题: ---------------答题活动:求π的值--------------- [打印本页]
作者: 杨增坤 时间: 2013-11-17 22:06
标题: ---------------答题活动:求π的值---------------
本帖最后由 杨增坤 于 2013-11-25 11:06 编辑
此活动结束了,大家有不懂的地方可以参考一下其他人的代码,现在大家可以查看了!有什么建议,大家可以提出来!
问题1:
根据公式求π的值,直到所加项小于1E-10位置。
解释:1E-10表示的是1.0*Math.pow(10,-10),10的-10次幂。
问题2:
根据第一题求出的π的值,求圆的面积,半径从键盘上录入。
要求:
1.要求写出自己观察的规律,写出你的答题思路。
2.要写出自己的详细注释,包括函数和类。
3.要对输入的半径进行判断。
4.结果贴出来,结果清晰:π,半径和面积
评分:
1.正确的求出π。1分
2.在(1)的基础上写出了详细的思路和想法。2分
3.利用正确的π正确的求出了圆的面积。1分
4.对出入的半径做了正确的判断和结果清晰。1分
满分为5分。根据大家做的情况会给出相应技术分。
技术分会在本活动结束或者结束前做出评分。
提示:
可以使用循环,也可以使用其他的方法。
如果公式不清楚,那么可以查看附件!
本活动截至时间为2013-11-24 中午12点
大家赶快行动起来吧,你们都是最棒的!!!
-
gongshi.png
(19.57 KB, 下载次数: 78)
公式附件
作者: 赵晓海 时间: 2013-11-17 23:10
公式看不清楚啊
作者: To 时间: 2013-11-17 23:53
{:soso_e179:}
作者: 赵晓海 时间: 2013-11-18 03:01
本帖最后由 赵晓海 于 2013-11-18 11:29 编辑
-
-
Demo.zip
4.65 KB, 下载次数: 247
作者: 蜀仙 时间: 2013-11-18 10:22
提交了, {:soso_e160:}
-
-
刘建国 863665854.zip
1.58 KB, 阅读权限: 100, 下载次数: 1
作者: 孤独站士 时间: 2013-11-18 13:03
本帖最后由 孤独站士 于 2013-11-18 14:24 编辑
/*
求π,就是在累乘的基础上做累加,解此题的关键在于怎么表示出累加的每一项;
观察得知每一项有一个通项表示:即num=(1.0/n)*leicheng(n)*Math.pow((1.0/2.0),n);
其中n为从1开始依次加2的奇数,而leicheng方法中,注意点就是最小项为1/2
*/
import javax.swing.JOptionPane;
class MyPI
{
public static void main(String[] args){
double π;
π=PI();
System.out.println("π="+π);
//半径,面积
double r=0.0,a=0.0;
//控制是否多次测试
String another="";
//定义变量接收用户输入的值,都是String类型
String str="";
do
{
str=JOptionPane.showInputDialog("请输入半径的值:");
//转换成数值类型
r=Double.parseDouble(str);
if(r<0){
//对话框作显示
JOptionPane.showMessageDialog(null,"半径不能为负数,继续测试");
another="y";
//跳到下一次循环
continue;
}
//调用面积方法
a=area(r);
JOptionPane.showMessageDialog(null,"半径为"+r+"\n面积为"+a);
another=JOptionPane.showInputDialog("是否继续测试:Y/N");
}while(another.equalsIgnoreCase("y"));
System.out.println("半径为"+r+" 面积为"+a);
}
//求π得方法,注意点是各种数值类型的取值范围。
public static double PI(){
//定义变量存储π
double π=0.0;
//计数器,从1开始,每一次加2
int n=1;
//代表每一项
double num=0.0;
//开始循环求值
do{
num=(1.0/n)*leicheng(n)*Math.pow((1.0/2.0),n);
π+=num;
n+=2;
}
while(num>1.0*Math.pow(10,-10));
return 6*π;
}
//代表括号里面的累乘,其中n只能是奇数
public static double leicheng(int n){
double a=1.0;
while(n!=1){
//代表累乘括号里面每一项,最小项为1/2
a*=(double)(n-2)/(n-1);
n-=2;
}
return a;
}
//处理面积
public static double area(double i){
double tmp;
tmp=i*i*PI();
return tmp;
}
}
作者: 张鹏 时间: 2013-11-18 13:10
- /*
- * 分析:每一项有三个部分:
- * 1、由1到小于指数的数构成的分数相乘如1/2, 3/4, 5/6
- * 2、分子为1,分母为指数的分数
- * 3、1/2也就是0.5的 指数次 次方
- */
- public class CalculatePI
- {
- // 计算每一项的值
- public static double getItem(long index)
- {
- // 存每一项的值
- double fraction = 1;
- // 计算由1到小于指数的数构成的分数相乘
- for ( long i = 1; i < index; i += 2 )
- {
- fraction *= (double) i / (i + 1);
- }
- // 乘以分子为1,分母为指数的分数
- fraction *= 1 / (double) index;
- // 乘以1/2也就是0.5的 指数次 次方
- fraction *= Math.pow(0.5, index);
- return fraction;
- }
- // 获取π的值
- public static double getPI()
- {
- // 精确标准数
- double precision = 1.0 * Math.pow(10, -10);
- // 每一项的数
- double result = 0;
- // 每一项的和
- double sum = 0;
- // 指数,为奇数
- long index = 1;
- // 计算每一项的结果,并判断是否到达指定的精确数
- while ( (result = getItem(index)) >= precision )
- {
- // 每一项相加
- sum += result;
- // 下一个指数
- index += 2;
- }
- // 每一项的总和乘以6为π的值
- return sum * 6;
- }
- public static void main(String[] args)
- {
- System.out.println("π的值为:" + getPI());
- }
- }
复制代码
- import java.util.Scanner;
- /*
- * 计算圆的面积
- */
- public class CalculateCircle
- {
- /*
- * 求圆的面积
- */
- public static double getArea(double radius)
- {
- // 圆的面积公式:π * R * R
- return CalculatePI.getPI() * radius * radius;
- }
- @SuppressWarnings("resource")
- public static void main(String[] args)
- {
- Scanner input = new Scanner(System.in);
- System.out.println("请输入半径:");
- double radius = 0;
- try
- {
- // 接收输入数据
- radius = input.nextDouble();
- } catch (Exception e)
- {
- System.out.println("你输入的半径有误!");
- return;
- }
- System.out.println("圆的面积为(小数):" + CalculateCircle.getArea(radius));
- System.out.println("圆的面积为(取整):" +Math.round(CalculateCircle.getArea(radius)));
- }
- }
复制代码
作者: aspoMAN 时间: 2013-11-18 14:35
- MathPI类 ps:不知道是不是有计算失误或者不精确的原因,π值不准确
- /*
- * 分析:根据公式得出:π/6=(2*n-3)/(2*n-2) * 1.0/(2*n-1) * 1.0*Math.pow((1.0/2), (2*n-1));
- * 详细分析见附件。
- *
- * 计算方法:(公式中第一项为1,第n项为n)
- * 1.求出公式中第一个参数的值:采用递归获得当前想的值(第一个括号)
- * 2.求出第二个参数:1/2n-1
- * 3.求出第三个参数(第二个括号中的值):1/2的2n-1次幂
- * 4.求出前三个参数相乘的值并与1E-10相比较,得到第一个成立的n值为5.
- * 5.带入公式求的π的值
- */
- /*
- * 此类用于
- * 求π的值
- */
- public class MathPI {
-
- //求的值
- final static double PI = getAllValue(5.0)*6;
- public static void main(String[] args) {
- // System.out.println(calFirst(5.0));
- //1.循环求所加项小于1E-10
- double i = 1;
- /*while(true) {
- if(getCurrentValue(i) < 1.0*Math.pow(10, -10)) {
- System.out.println("所加项小于10的-10次幂时的n值:" + i);
- return;
- }
- i ++;
- }*/
-
- //求π值
- System.out.println("π的值:" + getAllValue(5.0)*6);
- }
-
- //方法一:计算参数的值(第一个括号内的值)
- static double firstValue = 1.0;
- public static double calFirst(double n) {
- if(n == 1) {
- return firstValue *= 1.0;
- } else {
- //递归调用,知道n等于1
- return firstValue *= (2*n-3)/(2*n-2)*calFirst(n - 1);
- }
- }
-
- //方法二:符合规律1/1,1/3,1/5,1/7
- static double secondValue = 1;
- public static double calSecond(double n) {
- //得到1/2n-1
- return secondValue = 1.0/(2*n-1);
- }
-
- //方法三:计算1/2的n次幂
- static double thirdValue = 1.0;
- public static double calThird(double n) {
- //得到1/2的2n-1次幂
- return thirdValue = 1.0*Math.pow((1.0/2), (2*n-1));
- }
-
- //求当前项的值(一个元素)
- public static double getCurrentValue(double n) {
- return calFirst(n)*calSecond(n)*calThird(n);
- }
-
- //求π/6的值(将所有元素加起来)
- static double allValue = 0;
- public static double getAllValue(double n) {
- if(n == 1) {
- return allValue += 1.0/2;
- } else {
- return allValue += calFirst(n)*calSecond(n)*calThird(n) + getAllValue(n - 1);
- }
- }
- }
复制代码- 求圆的面积:PIUtils
- /*
- * 利用MathPI中求得的π值求圆的面积
- *
- * 直接计算方法:getResult
- */
- import java.util.Scanner;
- public class PIUtils {
- public static void main(String[] args) {
- //从键盘录入数据
- System.out.println("请输入半径(大于0)");
- double r = 0;
- Scanner s = new Scanner(System.in);
- try{
- //获取键盘录入的数据,进行异常捕捉
- r = s.nextDouble();
- } catch(Exception e) {
- throw new RuntimeException("您输入的类型有误");
- }
- System.out.println("面积为:" + getResult(r));
- }
- public static double getResult(double r) {
- //对得到的半径进行判断
- if(r <= 0) {
- System.out.println("您输入的值有误");
- System.exit(0);
- }
- //返回面积
- return MathPI.PI*r*r;
- }
- }
复制代码
作者: 天ya~_琼楼 时间: 2013-11-18 15:18
版主辛苦了!
-
-
梁程峰.zip
4.73 KB, 阅读权限: 100, 下载次数: 1
求π,计算圆面积
作者: 潇湘溪语 时间: 2013-11-18 16:20
/*
1、观察规律,分析公式:
①从第二项,第三项,第四项的括号内容,可以看出是累积乘法;
②括号后面的内容是1/2、1/5、1/7,分母为逐渐加2递增;
③最后的指数的幂数是3、5、7,和②的分母递增规律一致;
④先把右边除去1/2的其它项累加和求出,再求pi值即可。
2、步骤:
①先利用for循环,求出括号内容的累积乘法;由于循环多少次暂且不清楚,查资料可利用最大值替代;
②后面的分数和指数规律一致,且只是递增,并没有累加,可以列出通项公式;
③当项的值小于10的-10次幂时,停止循环,此时有一个综止判断;
④求出通项累加和,再加1/2,再乘以6,就是pi的值;
3、定义半径,求圆的面积:
①可以把Pi的值和圆的面积公式封装成一个类;
②然后利用主函数的特性,调用封装的函数进行运算即可。
*/
//定义一个名称为Pi类
class Pi
{
public static void setR(int r)//设置半径r的值
{
double x = 1, y, temp = 0, pi = 0;
for ( int i = 1; i<Integer.MAX_VALUE; i++)//Integer.MAX_VALUE,最整数型的最大值,即初始设置循环最大次数;
{
x *=(2*i-1.0)/(2*i);//这是公式括号内的累积乘法,并循环
y=1.0/(2*i+1.0)*Math.pow(0.5,(2*i+1.0));//这是括号后面的递增分数和指数的运算
if( x*y<1.0*Math.pow(10,-10) )//判断:当项的值小于10的-10次幂时,停止运算;
break;
temp += x*y;//通项累加和
pi = 6.0*(temp + 0.5);
}
System.out.println("π="+pi);
//S=πr^2
System.out.println("r="+r);
if(r>0)
System.out.println("S="+pi*r*r);
else
System.out.println("error");//面积不能为0和负数,只能为正
}
}
//定义一个PiDemo的类,可以调用上一个对象
class PiDemo
{
public static void main(String[] args)
{
Pi.setR(8);//输入半径为8或者任意数,即可得到结果,如下所示
}
}
/*
π=3.141592653258738
r=8
S=201.06192980855923
*/
作者: 赵晓海 时间: 2013-11-18 16:35
做了个公式,希望采纳{:soso_e113:}
作者: 赵晓海 时间: 2013-11-18 17:04
哇塞,还有分可以加,谢谢坤哥!
作者: 问天 时间: 2013-11-18 19:39
已提交,感谢版主给出建议
-
-
周学君.zip
1.34 KB, 阅读权限: 100, 下载次数: 1
作者: 王东 时间: 2013-11-18 19:49
作者: jttsai 时间: 2013-11-18 21:52
本帖最后由 jttsai 于 2013-11-19 08:59 编辑
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 思路: 从第二项开始观察(以加法来分开各个项),我们可以看出,第二项的第一个为1/2 ,而第三项的第一个为1/2 + 3/4,其中1/2 +
* 3/4比1/2多加了个3/4 其中3/4 可以看出(1+2)/(2+2),也就是分子分母都自增了2,第三个的第一项也是这个规律。
* 而各项的第二个数字分别为1/3,1/5,1/7,也是自增量为2 而各项的第三个数字,后一项是前一项的0.5*0.5倍。
* 输入半径匹配原则:开始字符只能为0-9数字而且一个或者多个,小数点有一个或者没有,如果有小数后面跟着一个0-9的小数,后面只能为0-9数字也可以有0个或者多个。
*
* @author Administrator
*
*/
public class TestNumSort {
public static void main(String[] args) {
double sum = 0.5, t, t1, t2, t3, p = 0.5 * 0.5;
int odd = 1, even = 2;
t = t1 = t2 = 1.0;
t3 = 0.5;
// 知道所加项小于1E-10
while (t > 1e-10) {
t1 = t1 * odd / even;
// 自增2
odd += 2;
// 自增2
even += 2;
t2 = 1.0 / odd;
t3 = t3 * p;
t = t1 * t2 * t3;
sum += t;
}
System.out.println("π的值为: " + sum * 6);
System.out.print("请输入半径:");
String regex = "\\d+(\\.\\d)?\\d*";
// 键盘录入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = "";
try {
line = br.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 输入的半径规则判断
if (!line.matches(regex)) {
System.out.print("输入数字不规范!");
return;
}
double r = Double.parseDouble(line);
System.out.println("圆的面积为 : " + (sum * 6 * r * r));
}
}
输出结果:
π的值为: 3.1415926535153385
请输入半径:1.34
圆的面积为 : 5.641043768652143
-
-
Demo.rar
3.56 KB, 下载次数: 187
作者: 向阳泪无痕 时间: 2013-11-19 10:50
本帖最后由 向阳泪无痕 于 2013-11-20 05:32 编辑
先抢个楼……
作者: 向阳泪无痕 时间: 2013-11-19 10:54
本帖最后由 向阳泪无痕 于 2013-11-20 10:58 编辑
- /*
- 问题1:
- 根据公式求π的值,直到所加项小于1E-10位置。
- 解释:1E-10表示的是1.0*Math.pow(10,-10),10的-10次幂。
- 问题2:
- 根据第一题求出的π的值,求圆的面积,半径从键盘上录入。
- 要求:
- 1.要求写出自己观察的规律,写出你的答题思路。
- 2.要写出自己的详细注释,包括函数和类。
- 3.要对输入的半径进行判断。
- 4.结果贴出来,结果清晰:π,半径和面积
- 问题1:
- 思路:
- 1,根据公式可知,这是一个无限加下去的公式,而每次所加的值都和其前后有着有关系,根据公式可知
- 这个公式中可能出现了等比,等差数列的组合,所以从这个角度去分析这个公式,找出他们每一项的通式。
- 则可采用for循环来叠加,求出更精确的PI值。
- 2,分析公式找到了通式,把公式先设成 PI/6 = 1/2 + Sn
- S由公式右边从第二项开始
- 公式Sn = (1/2)1/3(1/2)^3+(1/2*3/4)1/5(1/2)^5+(1/2*3/4*5/6)1/7(1/2)^7+.....
- = a1+a2+a3+....an
- S可看成由3部分组成 (n从1开始取)
- T1 : 就是每项的第一个括号括住的 每一项值分别是 1/2 1/2*3/4 1/2*3/4*5/6 1/2*3/4*5/6*... 通式 1/2*3/4*...*(2n-1)/2n
- T2 : 中间那个分数 每一项值是 1/3 1/5 1/7 1/9 ... 通式 1/(2n+1)
- T3 : 最后那个括号括及幂方 (1/2)^3 (1/2)^5 (1/2)^7 (1/2)^9 ... 通式 (1/2)^(2n+1)
- an = T1*T2*T3
- = [1/2*3/4*...*(2n-1)/2n] * 1/(2n+1) * (1/2)^(2n+1)
- 3,使用for循环叠加 当S的第n项小于1E-10位置时,结束循环。
- 步骤:
- 1,用上面方法求出S,使用for循环来求得
- 2,由:PI/6 = 1/2 + Sn
- 得PI = 3 + 6Sn
- 问题2:
- 思路:
- 1,从键盘录入圆的半径
- 2,使用IO流读出半径,因为从控制台读取,所以使用InputStream
- 3,使用问题1中求出的PI来求圆的面积
- 4,输出结果,可继续输入半径求圆面积
- 5,如不在用IO流,则关闭流。
- */
- import java.lang.Math.*;
- import java.io.*;
- class MathText
- {
- static double PI,Sn,T1,T2,T3,an; //定义求PI所须要的变量
- static BufferedReader bufr = null;
- static double radius; //用来保存圆半径
- static double area; //用来保存圆面积
- public static void main(String[] args)
- {
- //问题1
- sunText();
- //问题2
- roundArea();
- }
- //问题1
- public static void sunText()
- {
- //1,求出S值 ,Sn = a1+a2+a3+.....+an , an=T1*T2*T3
- for(int n = 1; ;n++) //通过S的通式,叠加每一项,n从1开始取
- {
- //求T1
- for(int i=1;i<=n;i++)
- {
- if(i==1) //第一次得第一项时,在此处初始化第一项
- T1 = 0.5;
- else
- T1 = T1 * ((2.0*n-1)/(2.0*n)); //第二项开始使用公式得T1
- }
- //求T2
- T2 = 1.0/(2.0*n+1);
- //求T3
- T3 = Math.pow(1.0/2.0,(2*n+1));
-
- //求第an项
- an = T1*T2*T3;
- if( an<(1E-10) ) //当所加项小于1E-10则结束叠加
- break; //然后结束叠加
- Sn += an; //把每一项叠加起来 Sn = a1+a2+a3+.....+an
-
- }
-
- //2,求出PI
- PI = 3 + 6*Sn; //结束循环就是加到要求的那个项了,则开始计算PI的值
- System.out.println("\n问题1:计算得 PI = "+PI);
- }
- //问题2
- public static void roundArea()
- {
- try
- {
- while(true)
- {
- //1,从键盘录入圆的半径,因为从控制台读取,所以使用InputStream
- System.out.print("\n请输入圆的半径 radius = ");
- bufr = new BufferedReader(new InputStreamReader(System.in));
- //2,使用IO流读出半径
- String s = bufr.readLine(); //读取失败抛IOException异常
- if("over".equals(s) || "OVER".equals(s)) //输入over结束求圆面积
- return;
-
- radius = Double.parseDouble(s); //转换失败抛NumberFormatException异常
- //3,使用问题1中求出的PI来求出圆的面积
- area = PI*radius*radius;
- //4,输出结果,可继续输入半径求圆面积
- System.out.println("->该圆的面积为 area = "+area);
-
- }
- }
- catch (IOException e)
- {
- System.out.println("读取数据失败");
- }
- catch(NumberFormatException ex)
- {
- //处理转换异常
- System.out.println("输入半径有错,请从新输入!");
- //半径输入错误,再从新输入求圆面积
- roundArea();
- }
- finally
- {
- //5,如不在用IO流,则关闭流。
- try
- {
- if(bufr!=null) //如果流创建成功,则才可关闭。
- bufr.close();
- }
- catch (Exception e)
- {
- System.out.println("关闭流资源错误!");
- }
- }
- }
- }
复制代码
作者: joure 时间: 2013-11-20 19:29
本帖最后由 joure 于 2013-11-22 10:48 编辑
/*一,观察规律:
通过观察规律第n项的值可以拆分为三部分表示
第一部分为 1~(2*n-3)的奇数除以2~(2*n-2)的偶数
第二部分为 1除以(2*n-1)
第三部分为 1/2的(2*n-1)次幂
思路:
使用循环嵌套解决问题
外循环控制运算次数,内循环算出单项的值
运算结果:
π的值为3.1415926535153385
*/
class PiDemo
{
public static void main(String[] args)
{
double pi;
double sum=0.5,sum_n=0.5; //sum表示的是右边算式总和,sum_n表示第n项的值
for (int n=2; sum_n>1.0*Math.pow(10,-10);n++ )//sum_n小于1E-10位置结束循环
{
double x=1.0;
for (int i=1; i<=(2*n-3); i=i+2)
{
x=x*i/(i+1); //算式括号内的值用x表示
}
sum_n =x*Math.pow(0.5,2*n-1)/(2*n-1); //求出单项值
sum=sum+sum_n; //求出右边算式总和
}
pi=6*sum; //π的值
System.out.println("π的值为"+pi);
}
}
/*
二,思路
利用π值求圆面积,使用scanner方法输入,利用公式求出圆面积并输出
输入数据判断是一个难点,也是我目前的一个盲点,所以第4个功能未能够实现
我会争取早日把这部分的内容学完,实现这个功能
运算结果:
请输入圆的半径:
5
圆的半径为:5
圆的面积为:78.53981633788347
*/
import java.util.*;
class Asd
{
public static void main(String[] args)
{
double pi=3.1415926535153385;
System.out.println("请输入圆的半径:");
Scanner input=new Scanner(System.in);
int r=input.nextInt();
System.out.println("圆的半径为:"+r+"\n"+"圆的面积为:"+pi*r*r);
}
}
总结:自己的基础太薄弱,做第一个问题的时候一连出了十几个错误,调试了大半天
使我意识到盲目追求进度是不可取的,必须把基础学扎实,才能提高后续的学习效率
作者: ysunday 时间: 2013-11-21 03:17
本帖最后由 ysunday 于 2013-11-21 03:20 编辑
- /*
- * 思路:
- * 1/2 + (1/2)*(1/3)*(1/2)^3 + (1/2*3/4)*(1/5)*(1/2)^5
- * 对除了第一项,每项可分为3部分,第一部分的规律是(1/2*3/4*5/6...(2n-3)*(2n-2)
- * 对于2和3部分可找规律为 1/(2n-1), (1/2)^(2n-1)
- *
- * 既然找出规律来,就先循环求出第n项,然后将n项累加,求出PI
- *
- * 对键盘录入,用户可能输入错误的格式,那就有可能异常,先捕捉异常,
- * 同时还得判断用户是否输入负数,如果用户输入错了,得让用户可以重新
- * 输入,故采用while
- */
- import java.text.DecimalFormat;
- import java.util.Scanner;
- public class Test10 {
- /**
- * @param args
- */
- public static void main(String[] args) {
- Scanner sc = new Scanner(System.in); //建立对控制台的输入的关联
- double PI = findPI(); //求出PI
- while(true){ //循环,直到用户输入正确的格式
- System.out.println("please input R:");//提示
- String s = sc.nextLine(); //读取一行
- Double r = null; //定义r
- try{
- r = Double.valueOf(s); //转型
- if(r < 0 || r == null){//判断是否为空,或者小于0,个人认为半径为0可接受
- //如果符合条件,进行下次循环,让用户输入
- System.out.println("R can't be less than
- zero,please input right format");
- continue; //跳出本次循环
- }
- //如果符合,计算面积,这里对结果进行了格式化,保留四位小数
- String area =
- new DecimalFormat("#.0000").format(PI * r * r);
- System.out.println("PI: " + PI);//输出PI和园的信息
- System.out.println("R:" + r + " Area:" + area);
- break; //结束循环
- }catch(Exception e){ //因为用户有可能输入的字符ab之类抓异常
- System.out.println("your input format is wrong, please a number");
- continue; //结束本次输入,进行下次
- }
- }
- sc.close(); //关闭资源
- }
- public static double nthNum(int n){//计算除第一个数之外的第n项值
- double nthNum = 1; //记录结果用
- double y = Math.pow(0.5, 2 * n - 1 + 0.0);//这是每项中间那部分的值
- for(int x = 2; x <= n; x = x + 1){ //循环n - 1次,因为没有第1项
- nthNum *= (2 * x - 3 + 0.0)/(2 * x - 2 + 0.0);//累乘
- }
- return nthNum * (1 / (2 * n - 1 + 0.0)) * y; //返回第n项的值
- }
- public static double findPI(){ //利用第n项,算最终的结果的函数
- double sum = 0.5; //第一项 1/2
- //各项累加,直到第n项小于等于给定值为止
- for(int x = 2;nthNum(x) >= Math.pow(10.0, -10.0); x++){
- sum += nthNum(x);
- }
- return sum * 6; //返回PI
- }
- }
复制代码
谢谢您的批阅!您辛苦了
作者: 瓶中人 时间: 2013-11-23 21:10
package com.ping.test;
import java.util.Scanner;
public class PI {
/**
* 题目:根据公式求π值
* 思路:
* 1.π的值等于右边的值乘以6,所以就是要求右边的值即可
* 2.由右边公式可知,其实“+”号间的数字段都是分为三个公式相乘而来,
* 如((1/2)*(3/4)*(5/6))*(1/7)*(1/2)的七次方 ,可分为((1/2)*(3/4)*(5/6))、 (1/7) 与 (1/2)的七次方
* 3.只需要观察每个公式的规律即可,其中一个段(1/2)可以想成1*1*(1/2)
* 4.解第一个公式,提取提供资料的4段数字分别为:1 、1/2、(1/2)*(3/4)、((1/2)*(3/4)*(5/6))
* ,由相乘数字递增就可知这就是一个循环递增的相乘所得,每段都可在前面加“1*”,由((1/2)*(3/4)*(5/6))
* 可知其每项的分子比分母少一,而个分母都比前一个数的分母多2,当然除了第个公式除外,所以单独把它划出(if(j==1)num1=1;),
* 原来是这个的((2*j-1) /(2*j)),不过如果第一项的特殊的关系,改为((1-(2*(j-1)))j不等于1)
* 5,解第二个公式,同样从4段式子中抽取数字分别为 1,(1/3),(1/5),(1/7)可知,其分子均为1,而分母的关系是 ((2*j) -1)
* 6,解第三个公式 同样从4段式子中抽取数字分别为 1/2,(1/2)³,(1/2)5次方,(1/2)七次方,很容易就可以想出(1/2)(2-1)次方
* 7,就这样将其分别循环,再将一次循环所得相乘,再在外循环中相加,直到其满足条件后跳出外循环。
* 8,其中需要注意因其主要是小数计算,所以是不能用int 类型定义变量,而且不能写(1/2)因其两者皆为int,相除结果只会为0
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//调用manager()
manager();
}
public static void manager(){
//新建Scanner对象
Scanner input = new Scanner(System.in);
System.out.println("请输入圆的半径:");
//输入半径
double radius = 0;
//用捕获异常的方法是为了防止输入异常字符
try {
radius = input.nextDouble();
//判断其是否为正整数
if(radius <= 0){
System.out.println("请输入大于0的数字!");
}
//按要求输入半径,圆周率与面积
System.out.println("圆的半径为:"+ getPI()+",半径为:"+radius +",圆的面积为:" + getPI() * radius * radius);
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("请输入数字!");
}
}
//计算π的方法
public static double getPI(){
//定义变量
//右边的数之和
double sum = 0;
//循环变量
double i = 1 ;
//设外循环为死循环,满足条件即跳出
while(true){
//每段数字的和的变量
double littleSum = 0;
//第一个公式的和
double num1 = 1;
//第二个公式的和
double num2 = 0;
//第三个公式的和
double num3 = 1;
//第一个公式的和的计算方法
for(double j = 1 ; j <= (i * 2 -1) ; j ++){
num1 *= 0.5 ;
}
//第二个公式的计算方法
num2 = 1 /(2 * i -1);
//第三个公式的计算方法
for(double j = 1 ; j <= i ; j ++){
if(j==1)
//将情况为1的区别出来
num3 = 1 ;
else
num3 *= 1 - 1 /((j -1) *2);
}
//第一段公式之和
littleSum = num1 * num2 * num3;
//所有段的公式相加
sum += littleSum;
i++;
//若满足条件,即跳出循环
if(littleSum < 1.0*Math.pow(10, -10)){
break;
}
}
//因π等于 右边之和 乘以 6
return sum * 6;
}
}
作者: Linuxgg 时间: 2014-2-23 18:03
#在这里快速回复#谢谢楼主期望灌水,我是来拿技术分 Sun Feb 23 18:03:30 CST 2014
作者: Linuxgg 时间: 2014-2-23 20:38
#在这里快速回复#谢谢楼主期望灌水,我是来拿技术分 Sun Feb 23 20:38:20 CST 2014
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |