
标题: [其他] 一个c++程序,求指点,送祭扫 [打印本页]
作者: ylara 时间: 2012-11-7 21:26 标题: 一个c++程序,求指点,送祭扫
利用格里高利公式编写程序求π。
π/4=1-1/3+1/5-1/7+……
直到最后一项的值小于10-6为止。
#include <iostream.h>
void main()
{
int a,b,i;
double x=0;
for (a=1,b=1,i=0; (1/b)>0.00001; b=b+2,a=b*(-1)^i,i++)
{
x=x+1/a;
}
cout<<x;
}
我是这样想的, (1/b)>0.00001用来控制精度,因为b恒正。
b=b+2,a=b*(-1)^i,i++。这句用来控制a的变化是1,-3,5,-7.。。。
然后做x,感觉挺对的,但是输出结果是1,。
刚学,求指导。
[ 本帖最后由 ylara 于 2012-11-7 22:07 编辑 ]
作者: ffcactus 时间: 2012-11-7 21:34
posted by wap, platform: iPhone
首先你的程序不直观。for 寻坏最好用一个步进2的整数记数器,同时用作分母。循环中设置加减符号反转变量。这样你也无需考虑正负就能得到循环退出的条件。
这样写的程序别人知道这个公式的话,看你程序就知道你在干嘛。
作者: ylara 时间: 2012-11-7 21:57
我这里的加减反转变量就是(-1)^i,i++啊引用:
原帖由 ffcactus 于 2012-11-7 21:34 发表 
posted by wap, platform: iPhone
首先你的程序不直观。for 寻坏最好用一个步进2的整数记数器,同时用作分母。循环中设置加减符号反转变量。这样你也无需考虑正负就能得到循环退出的条件。
这样写的程序别人知道这 ...
作者: ffcactus 时间: 2012-11-7 22:13
posted by wap, platform: iPhone
你这反转比用if(a==1) a=0; else a=1; 要慢几十倍。而且一般人看不懂。
作者: ffcactus 时间: 2012-11-7 22:16
posted by wap, platform: iPhone
好像整数除整数不会变浮点吧。
作者: yanger 时间: 2012-11-7 22:19
1/a后面都是0了?
[ 本帖最后由 yanger 于 2012-11-7 22:22 编辑 ]
作者: ffcactus 时间: 2012-11-7 22:29
posted by wap, platform: iPhone
Double x=0;
for(long a=1, int f=0; a < 100000; a+=2) {
if(f++ == 0)
x+= ( 1.0f / a );
else {
f--;
x-= ( 1.0f / a );
}
}
Cout << x *4 << endl;
作者: hourousha 时间: 2012-11-7 22:37
费那么多话直接给个程序不得了?
#include <iostream>
void main()
{
double denominator = 1.0;
double pi=0.0;
double signflag = 1.0;
while(denominator<=100000.0)
{
pi += signflag/denominator;
denominator += 2.0;
signflag *= -1.0;
}
pi *= 4.0;
std::cout<<pi<<std::endl;
}
作者: lvcha 时间: 2012-11-7 22:43
a是int,除了1分之一是1以外其它都是0啊
不好意思c++还是中学课外班学的早忘了。
按java来说你 改成 x+1.0/(double)a就好了
话说你的程序是为了不让人读懂么?
这么写太不专业了。
作者: lvcha 时间: 2012-11-7 22:46
前面也不对。
你a和b直接声明double不就得了。干啥int啊。
作者: ylara 时间: 2012-11-7 22:47
。。。我的错我的错引用:
原帖由 lvcha 于 2012-11-7 22:43 发表 
a是int,除了1分之一是1以外其它都是0啊
不好意思c++还是中学课外班学的早忘了。
按java来说你 改成 x+1.0/(double)a就好了
话说你的程序是为了不让人读懂么?
这么写太不专业了。
作者: karsus 时间: 2012-11-7 22:53
引用:
原帖由 hourousha 于 2012-11-7 22:37 发表 
费那么多话直接给个程序不得了?
#include
void main()
{
double denominator = 1.0;
double pi=0.0;
double signflag = 1.0;
while(denominator
signflag 和denominator定义的时候需要用Int,运算中强转成double,不然连续相加和相乘有浮点误差
看错
[ 本帖最后由 karsus 于 2012-11-7 22:57 编辑 ]
作者: lvcha 时间: 2012-11-7 22:55
引用:
原帖由 karsus 于 2012-11-7 22:53 发表 
signflag 和denominator定义的时候需要用Int,运算中强转成double,不然连续相加和相乘有浮点误差
这样啊,java里加个strictfp关键字就好了。
作者: sumeru 时间: 2012-11-7 23:05
这种程序Fortran最擅长,c/c++的话要考虑很多精度误差以及类型转换的问题。
作者: hourousha 时间: 2012-11-7 23:14
引用:
原帖由 karsus 于 2012-11-7 22:53 发表 
signflag 和denominator定义的时候需要用Int,运算中强转成double,不然连续相加和相乘有浮点误差
signflag完全没必要做这种处理。因为-1.0的寄存器内存储形式是0xBFF0000000000000,而1.0的存储是0x3FF0000000000000,根据浮点乘法运算的原理,无论乘多少次也不会出岔子的。
浮点容易出问题的是在加减法,因为存在指数位对齐操作导致的尾数位移位操作。因此从理论上denominator做你说的操作并非完全无用,不过实际上那种累计式误差,主要存在于对一个变量的连续迭代上,像这种只是以常数值递增的情况,误差是可以忽略的。尤其是它的值并不很大的情况。
其实就一般习惯来说,只要注意别对浮点数使用==来判断也就差不多了。
如果要做高精度运算,一般都是不是用浮点数来做的。当然LZ这个公式的收敛速度之慢也不是高精度计算pi用的公式。
作者: tobewind 时间: 2012-11-8 00:46
喷了,和八楼差不多,我不是故意的。
根据楼主的逻辑,稍微改改:
1 楼主的bug,是因为没有在值赋给result之前对其进行强制类型转换操作
2 楼主没有简化逻辑。
3 (1/b)>0.00001 为什么不写成 b > 100000?
4 让自己适应一种编码风格。代码不带空格拧巴在一起看了很难受。复制内容到剪贴板
代码:
#include <iostream>
int main()
{
int a, b;
a = b = 1;
double result = 0;
while( a < 1000000) {
result += (double) b / a;
a += 2;
b = -b;
}
std::cout << 4 * result;
return 0;
}
[ 本帖最后由 tobewind 于 2012-11-8 00:48 编辑 ]
作者: msforza 时间: 2012-11-8 00:56
posted by wap, platform: iPhone
钓鱼贴,楼上所有人好人一生平安
作者: Mozi 时间: 2012-11-8 08:18
for里面放这么多东西, 果然是第一天上手c++.
作者: chenxiao07 时间: 2012-11-8 13:16
其实计算PI用这个方法也不错,不用外部数据类型,也能计算到小数点后面800位呢复制内容到剪贴板
代码:
int a=10000,b,c=2800,d,e,f[2801],g;
main() {
for(;b-c;)
f[b++]=a/5;
for(;d=0,g=c*2;c -=14,printf("%.4d",e+d/a),e=d%a)
for(b=c; d+=f[b]*a,f[b]=d%--g,d/=g--,--b; d*=b);
}
[ 本帖最后由 chenxiao07 于 2012-11-8 13:17 编辑 ]
作者: seek 时间: 2012-11-8 23:47
留名..
tg死程在本帖集结。。
欢迎光临 TGFC Lifestyle (http://bbs.tgfcer.com/) |
Powered by Discuz! 6.0.0 |