需要帮助修复近似pi的算法 [英] Need help fixing an algorithm that approximates pi

查看:112
本文介绍了需要帮助修复近似pi的算法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为近似 pi 的算法编写C代码.它应该得到一个立方体的体积和那个立方体内部的球体的体积(球体的半径是立方体的侧面的1/2).然后我应该将立方体的体积除以球体的体积,然后乘以6得到pi.

I'm trying to write the C code for an algorithm that approximates pi. It's supposed to get the volume of a cube and the volume of a sphere inside that cube (the sphere's radius is 1/2 of the cube's side). Then I am supposed to divide the cube's volume by the sphere's and multiply by 6 to get pi.

它正在工作,但是在应该获得体积的部分中却做了一些奇怪的事情.我认为这与我为近似值选择的增量有关. 有了方4的立方体,而不是给我64的体积,它给了我6400.使用球体而不是33,给了我3334.

It's working but it's doing something weird in the part that is supposed to get the volumes. I figure it's something to do the with delta I chose for the approximations. With a cube of side 4 instead of giving me a volume of 64 it's giving me 6400. With the sphere instead of 33 it's giving me 3334. something.

有人能弄清楚吗?这是代码(我对相关部分进行了注释):

Can someone figure it out? Here is the code (I commented the relevant parts):

#include <stdio.h>      

int in_esfera(double x, double y, double z, double r_esfera){
    double dist = (x-r_esfera)*(x-r_esfera) + (y-r_esfera)*(y-r_esfera) + (z-r_esfera)*(z-r_esfera);

    return  dist <= (r_esfera)*(r_esfera) ? 1 : 0;   
}   

double get_pi(double l_cubo){   
    double r_esfera = l_cubo/2;   
    double total = 0;
    double esfera = 0;    
//this is delta, for the precision. If I set it to 1E anything less than -1 the program continues endlessly. Is this normal?
    double delta = (1E-1);   

    for(double x = 0; x < l_cubo; x+=delta){
        printf("x => %f; delta => %.6f\n",x,delta);
        for(double y = 0; y <l_cubo; y+=delta){
            printf("y => %f; delta => %.6f\n",y,delta);
            for(double z = 0; z < l_cubo; z+=delta){
                printf("z => %f; delta => %.6f\n",z,delta);
                total+=delta;
                if(in_esfera(x,y,z,r_esfera))
                    esfera+=delta;
            }
        }
    }

    //attempt at fixing this
        //esfera/=delta;
        //total/=delta;
    //

//This printf displays the volumes. Notice how the place of the point is off. If delta isn't a power of 10 the values are completely wrong.   
    printf("v_sphere = %.8f; v_cube = %.8f\n",esfera,total);   

    return (esfera)/(total)*6;
}   

void teste_pi(){        
    double l_cubo = 4;    
    double pi = get_pi(l_cubo);

    printf("%.8f\n",pi);
}   

int main(){   
    teste_pi();
}

推荐答案

事情是,像a * b * c这样的整数上乘以与将1 + 1 + 1 + 1 + ... + 1 a * b * c乘以相同,对吗?

The thing is that multiplication over integers like a * b * c is the same as adding 1 + 1 + 1 + 1 + ... + 1 a * b * c times, right?

您要添加delta + delta + ... (x / delta) * (y / delta) * (z / delta)次.换句话说,就是(x * y * z) / (delta ** 3)次.

You're adding delta + delta + ... (x / delta) * (y / delta) * (z / delta) times. Or, in other words, (x * y * z) / (delta ** 3) times.

现在,delta s的总和与此相同:

Now, that sum of deltas is the same as this:

delta * (1 + 1 + 1 + 1 + ...)
         ^^^^^^^^^^^^^^^^^^^^ (x * y * z) / (delta**3) times

因此,如果delta是10的幂,则(x * y * z) / (delta**3)将是一个整数,并且将等于括号中1的总和(因为它与 product 相同) > x * y * (z / (delta**3)),其中最后一项是整数-请参阅此答案的第一句).因此,您的结果将如下所示:

So, if delta is a power of 10, (x * y * z) / (delta**3) will be an integer, and it'll be equal to the sum of 1's in parentheses (because it's the same as the product x * y * (z / (delta**3)), where the last term is an integer - see the very first sentence of this answer). Thus, your result will be the following:

delta * ( (x * y * z) / (delta ** 3) ) == (x * y * z) / (delta**2)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the sum of ones

这就是您最终计算乘积除以delta平方的方式.

That's how you ended up calculating the product divided by delta squared.

要解决此问题,请将所有体积乘以delta * delta.

To solve this, multiply all volumes by delta * delta.

但是,我认为不可能将这种逻辑用于功率不为10的delta.而且,实际上,代码会为delta == 0.21l_cubo == 2带来各种麻烦,例如:您将得到9.261000000000061而不是8.

However, I don't think it's possible to use this logic for deltas that aren't a power of 10. And indeed, the code will go all kinds of haywire for delta == 0.21 and l_cubo == 2, for example: you'll get 9.261000000000061 instead of 8.

这篇关于需要帮助修复近似pi的算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆