一个简单的问题

lixzhang 2007-10-16 05:34:11
编写一个Java应用程序,计算1-1/3+1/5-1/7+1/9-1/11+…..的前10000项之和。要求结果是分数,我编了一个感觉有点复杂 有没有简单点的?
...全文
373 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
这是一个发散数列,没有求和公式,可以试着将结果乘以 4,你会发现一个熟悉的数。
对了,当数列趋向无穷时,它的值为 pi/4
lixzhang 2007-10-18
  • 打赏
  • 举报
回复
楼上说的很有道理 开始我也是这样想的 估计可以找到一个通项,那样会简单一点。但是就是要用到通项也还是要一项一项的加。像你说的-1的n次方除以(2n-1)我想每个人编程序时都用到了 不然就不好表示一般的情况了~~~


这个问题我想主要在于数值太大上。如果数值小的话 7楼的那个程序就蛮简洁~
lihaifeng0412 2007-10-17
  • 打赏
  • 举报
回复
ding
  • 打赏
  • 举报
回复
看来只能使用 BigInteger 自己实现一个 Fraction 了,最讨厌的是要进行约分。
  • 打赏
  • 举报
回复
数字太大了,Commons 的 Fraction 会溢出。
piaopiao11 2007-10-17
  • 打赏
  • 举报
回复
Commons 的包也不行,数值太大
Exception in thread "main" java.lang.ArithmeticException: Integer overflow
at org.apache.commons.lang.math.Fraction.add(Fraction.java:602)
报错
  • 打赏
  • 举报
回复
可以使用 Apache Commons 类库,有个 lang 包,其中有 org.apache.commons.lang.math.Fraction 类,
或者使用 org.apache.commons.math 包,都是可以的,基本都是差不多的,其中 lang 中的是静态方法。

这些里面有的是关于分数运算的操作,没有必要自己再去实现了。

Commons 类库,可能已经被你引用了也说不定,几乎所有的开源框架都会引用这个包的,
找一下 commons-lang.jar 就是了,或者到 Apache 的网站上去下载:

Commons Lang: http://commons.apache.org/downloads/download_lang.cgi
Commons Math: http://commons.apache.org/downloads/download_math.cgi



piaopiao11 2007-10-17
  • 打赏
  • 举报
回复
结果长度都有77337
太大了,贴不上来,也没法做约分
如果每次+的时候都约分 循环次数太多很慢。。。计算不出结果

期待有人给一个好的计算方法。。。
piaopiao11 2007-10-17
  • 打赏
  • 举报
回复
class A{
BigInteger x,y;

public A(int x, int y) {
this.x=new BigInteger(x+"");this.y=new BigInteger(y+"");
}
public void add(A a){
BigInteger x1=a.x.multiply(y).add(x.multiply(a.y));
BigInteger y1=a.y.multiply(y);
x=x1;
y=y1;

}

public String toString(){
return x+"/"+y;
}
}

A sum=new A(0,1);
for(int i=0;i<1000;i++){
A a;
if (i % 2 == 0){
a = new A(1,2*i+1);
}
else{
a =new A(-1,2*i+1);
}

sum.add(a);
}
System.out.println(sum);
fsolsh 2007-10-17
  • 打赏
  • 举报
回复
大家在回答问题之前
请先看清楚楼主在问什么
问题:【编写一个Java应用程序,计算1-1/3+1/5-1/7+1/9-1/11+…..的前10000项之和。要求结果是分数】
请注意,要求结果是分数,所以,要分别求出分子和分母,而不是直接运算出结果,因此需要找规律。
这个问题,可能高中的学生更容易做出来。


关注中……
piaopiao11 2007-10-17
  • 打赏
  • 举报
回复
数值太大了,太恐怖。
lixzhang 2007-10-17
  • 打赏
  • 举报
回复
还望个为赐教,看我那个哪里有毛病,前面都对,就是到后面就不对了。不相信可以只算前几项之和 然后口算验证~
tianshanaoxue 2007-10-17
  • 打赏
  • 举报
回复

public class qiuhe {
public static void main(String args[])
{
int n=1,a;
double sum=0.0,b;
while(n<=10000)
{
if(n%2==0)
a=-1;
else
a=1;
b=2*n-1;
sum=sum+a/b;
n++;
}
System.out.println("Sum : "+sum);
}
}
求类似的东西我认为应该先找适合每一项通项公式, 这个式子的每一项的通项公式为-1的n次方除以(2n-1)
chllcy 2007-10-17
  • 打赏
  • 举报
回复
火龙果牛!!!崇拜一下。。。。。
  • 打赏
  • 举报
回复
把 doubleValue() 方法去掉,改为 bigDecimalValue() 方法,这样可以
与 double 结果相比对了。


/**
* 返回 BigDecimal 值
* @param scale 有效精度
* @return
*/
public BigDecimal bigDecimalValue(int scale) {
BigDecimal num = new BigDecimal(numerator.toString());
BigDecimal deno = new BigDecimal(denominator.toString());
BigDecimal result = num.divide(deno, scale, BigDecimal.ROUND_HALF_UP);
return result;
}


计算结果:

约分前:38668 位
约分后:8672 位
分数计算的20位精度值:0.78537316339751080961
double运行值:0.7853731633975086

可见 double 的值是有误差的。
piaopiao11 2007-10-17
  • 打赏
  • 举报
回复
可以在每次相+前先求公约数,这样也很快

class A{
BigInteger x,y;

public A(int x, int y) {
this.x=new BigInteger(x+"");this.y=new BigInteger(y+"");
}
public void add(A a){
BigInteger b=y.gcd(a.y);//先求公约数在+

BigInteger x1=a.x.multiply(y).add(x.multiply(a.y));
BigInteger y1=a.y.multiply(y);

x=x1.divide(b);
y=y1.divide(b);

}
public void x(){//约分
BigInteger n=y.gcd(x);
System.out.println(n);
y=y.divide(n);
x=x.divide(n);

}

public String toString(){
return x+"/"+y;
}
}


A sum= new A(0,1);
for(int i=0;i<10000;i++){
A a;
if (i % 2 == 0){
a = new A(1,2*i+1);
}
else{
a = new A(-1,2*i+1);
}
sum.add(a);
}
System.out.println(sum.toString().length());
sum.x();
//double x=sum.x.doubleValue();
//double y=sum.y.doubleValue();
System.out.println(sum.x.toString().length());
piaopiao11 2007-10-17
  • 打赏
  • 举报
回复
想不到BigInteger 已经自带的最大共约数的求法,确实结果是8672位,
  • 打赏
  • 举报
回复
大多数的时间都浪费在约分上了,把约分放到最后做只要很短时间就出来了,
约分之前的分子分母有 38668 位,约分之后为 8672 位。

更改后的 main 方法,如下:

public class FractionTest {

public static void main(String[] args) {
int numerator = -1;
MyFraction fra = new MyFraction(0, 1);
double d = 0;
for (int i = 1; i <= 10000; i++) {
numerator = -numerator;
fra = fra.add(new MyFraction(numerator, 2 * i - 1));
d += ((double) (numerator)) / (2 * i - 1);
}
// 把约分放到最后做,可以大大地提高运行速度
fra.reduce();
System.out.println(fra.getNumerator().toString().length());
System.out.println(fra.getDenominator().toString().length());
System.out.println(d);
}
}
  • 打赏
  • 举报
回复
前项数少一点的话运行正确,可以计算 doubleValue,结果是正确的,
如计算 10000 项,需要运行大概 5 分钟,分子和分母都有 8672 位,
也不知道是否正确。

public class FractionTest {

public static void main(String[] args) {
int numerator = -1;
MyFraction fra = new MyFraction(0, 1);
double d = 0;
for (int i = 1; i <= 10000; i++) {
numerator = -numerator;
fra = fra.add(new MyFraction(numerator, 2 * i - 1));
d += ((double) (numerator)) / (2 * i - 1);
fra.reduce(); // 约分
if (i % 1000 == 0) {
System.out.println(i);
}
}
System.out.println(fra.getNumerator().toString().length());
System.out.println(fra.getDenominator().toString().length());
System.out.println(d);
}
}

class MyFraction {
private BigInteger numerator;
private BigInteger denominator;

public MyFraction(int numerator, int denominator) {
this.numerator = new BigInteger(numerator + "");
this.denominator = new BigInteger(denominator + "");
}

public MyFraction(BigInteger numerator, BigInteger denominator) {
this.numerator = numerator;
this.denominator = denominator;
}

public MyFraction add(MyFraction fra) {
BigInteger num1 = this.numerator.multiply(fra.denominator);
BigInteger num2 = fra.numerator.multiply(this.denominator);
BigInteger num = num1.add(num2);
BigInteger den = this.denominator.multiply(fra.denominator);
return new MyFraction(num, den);
}

public void reduce() {
BigInteger gcd = numerator.abs().gcd(denominator);
numerator = numerator.divide(gcd);
denominator = denominator.divide(gcd);
}

public MyFraction getReducedFraction() {
BigInteger gcd = numerator.abs().gcd(denominator);
return new MyFraction(numerator.divide(gcd), denominator.divide(gcd));
}

public double doubleValue() {
return numerator.doubleValue() / denominator.doubleValue();
}

public BigInteger getDenominator() {
return denominator;
}

public BigInteger getNumerator() {
return numerator;
}
}
piaopiao11 2007-10-17
  • 打赏
  • 举报
回复
结果比天文数字还恐怖,想想10000!有多大。。。
用BigInteger可以计算但没法约分了。
分子和分母都在3万位以上,简直没法做任何处理
加载更多回复(12)

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧