¿Cómo puedo calcular el valor de PI con C#?

Yo estaba pensando que sería a través de una función recursiva, si es así, ¿cuál sería y ecuaciones matemáticas para la copia de seguridad?

Yo no soy demasiado exigente con el rendimiento, principalmente en la manera de ir sobre ella desde un punto de vista del aprendizaje.

  • Esta pregunta tiene un montón de buenas soluciones desde una perspectiva algorítmica. Yo no pensaría que iba a ser duro para adaptarse a uno de ellos para c#.
InformationsquelleAutor GateKiller | 2008-09-02

21 Comentarios

  1. 42

    Si quieres recursividad:

    PI = 2 * (1 + 1/3 * (1 + 2/5 * (1 + 3/7 * (...))))

    Esto vendría a ser, después de algunos reescritura:

    PI = 2 * F(1);

    con F(i):

    double F (int i) {
        return 1 + i / (2.0 * i + 1) * F(i + 1);
    }

    Isaac Newton (usted puede haber oído hablar de él antes 😉 ), vino con este truco.
    Tenga en cuenta que me fui de la condición final, para mantenerlo simple. En la vida real, una especie de necesidad de uno.

    • También, usted necesita devolver un valor?
    • No tiene una condición de terminación o un valor de retorno. Si desea crear un completo ejemplo de trabajo sugiero que publiques una nueva respuesta. Ver el comentario en la respuesta Note that I left out the end condition, to keep it simple. In real life, you kind of need one.
    • ¿cómo es que esto de tener tantos upvotes? esto no regresar nada
    • Es teórico, es por eso que no devuelve nada. Debe definir una precisión
    • He hecho la definición de F() devuelven, para aquellos de ustedes que encontrar ese tipo de cosas importantes. Creo que la idea principal era claro antes de pesar. Yo no estoy familiarizado con C#, y estoy acostumbrado a los idiomas que tienen implícito devuelve.
    • Para aquellos de ustedes que están interesados, esto se llama el poder de la serie

  2. 23

    Cómo sobre el uso de:

    double pi = Math.PI;

    Si quieres una mejor precisión de eso, usted tendrá que utilizar un sistema algorítmico y el tipo Decimal.

    • Creo que es un caso raro cuando usted necesita para tener más precisión de lo que recibe de las Matemáticas.PI;
    • En estos casos no se puede utilizar el doble, pero necesita una biblioteca para números de precisión arbitraria.
    • En el día de pi y en un pi hackaton voy a tener más precisión que este.
    • ha. no es realmente la respuesta que estaban buscando con calculate es la palabra operativa y de todos. Math.PI es una constante.
  3. 7

    Si usted toma una mirada más de cerca a esta muy buena guía:

    Pautas para la Programación en Paralelo: la Comprensión y Aplicación de Patrones Paralelos con el .NET Framework 4

    Que usted encontrará en la Página 70 este lindo aplicación (con pequeños cambios de mi lado):

    static decimal ParallelPartitionerPi(int steps)
    {
        decimal sum = 0.0;
        decimal step = 1.0 / (decimal)steps;
        object obj = new object();
    
        Parallel.ForEach(
            Partitioner.Create(0, steps),
            () => 0.0,
            (range, state, partial) =>
            {
                for (int i = range.Item1; i < range.Item2; i++)
                {
                    decimal x = (i - 0.5) * step;
                    partial += 4.0 / (1.0 + x * x);
                }
    
                return partial;
            },
            partial => { lock (obj) sum += partial; });
    
        return step * sum;
    }
    • +1 muy Interesante el enfoque que es muy rápido. Pero más allá del hecho de que este no se compila como es (que puede modificar si se desea), también no funciona. De todos modos, mi punto es que, una vez que lo tienes a la derecha y el valor que se parece a ‘parecer’ PI, tomar una mirada más profunda y verás el último decimales que da son bastante inexactos y … cambiando de cada carrera. El double la versión de que el doc tiene el mismo problema, pero el decimal uno no es más precisa.
  4. 6

    Hay un par de muy, muy viejos trucos me sorprende no ver aquí.

    atan(1) == PI/4, por lo que un viejo castaño cuando una persona de confianza de arco-tangente de la función es
    el presente es de 4*atan(1).

    Un muy lindo, con relación fija la estimación que hace el viejo Oeste 22/7 aspecto de suciedad
    es 355/113, lo cual es bueno para varias posiciones decimales (por lo menos tres o cuatro, creo).
    En algunos casos, esto es aún lo suficientemente bueno para la aritmética de enteros: multiplicar por 355 luego se divide por 113.

    355/113 también es fácil de recordar de memoria (para algunas personas, de todos modos): número uno, uno, tres, tres, cinco, cinco y recuerda que estás en la nomenclatura de los dígitos en el denominador y el numerador (si usted se olvida de que triplete va en la parte superior, un microsegundo del pensamiento es generalmente va a enderezar hacia fuera).

    Nota que 22/7 te ofrece: 3.14285714, lo que está mal en el milésimas.

    355/113 le da 3.14159292 que no está mal hasta el diez millonésimas.

    Acc. a /usr/include/matemáticas.h en mi caja, M_PI es #define d como:
    3.14159265358979323846
    que es probablemente bueno como como va.

    La lección que se obtiene de la estimación de PI es que hay un montón de maneras de hacerlo,
    ninguno va a ser perfecta, y usted tiene que ordenar por intención de uso.

    355/113 es un viejo Chino estimación, y yo creo que es la pre-fechas 22/7 por muchos años. Fue enseñado por un profesor de física cuando yo era un estudiante.

    • Me sorprende que en el 22/7. Además de utilizar los números enteros, ¿cómo podría tener algún uso práctico, dada su 2-decimal-lugar exactitud? Es decir, la constante numérica 3.14 no requiere cálculo, es el mismo número de caracteres, y es memorizado por todo el mundo. Esto trae a la mente el chiste de los Simpsons «pi es exactamente 3!», gritó alguien para conseguir la atención de un ahora-horrorizado-y-sala silenciosa de los conflictos de los profesores. 🙂
  5. 4

    Buena visión general de los diferentes algoritmos:

    No estoy seguro acerca de la complejidad reclamados por el de Gauss-Legendre-Salamin algoritmo en el primer enlace (yo diría que O(N log^2(N) log(log(N)))).

    Me animo a probarlo, sin embargo, la convergencia es realmente rápido.

    También, no estoy realmente seguro de por qué intentar convertir un muy simple procedimiento del algoritmo en un recursiva uno?

    Tenga en cuenta que si usted está interesado en el rendimiento, que entonces trabajaba en un almacén de precisión (por lo general, requieren de un ‘doble’, ‘float’,… de salida) en realidad no tiene sentido, ya que la respuesta obvia en este caso es sólo para codificar el valor.

  6. 2

    ¿Qué es PI? La circunferencia de un círculo, dividido por su diámetro.

    En gráficos de computadora puede trazar o dibujar un círculo con su centro en 0,0 a partir de un punto inicial x,y, el siguiente punto x’,y’ se puede encontrar utilizando una fórmula simple:
    x’ = x + y /h : y’ = y – x’ /h

    h es generalmente una potencia de 2, por lo que la brecha se puede hacer fácilmente con un cambio (o se resta el exponente en una doble). h también quiere ser el radio r de su círculo. Un fácil punto de inicio sería x = r, y = 0 y, a continuación, a contar c el número de pasos hasta x <= 0 para trazar un cuarto de círculo. PI es 4 * c /r o PI es 4 * c /h

    La recursividad a cualquier profundidad, que generalmente es poco práctico para un programa comercial, pero la cola de la recursividad permite un algoritmo para ser expresado de forma recursiva, mientras se implementa como un bucle. Recursiva de los algoritmos de búsqueda a veces puede ser implementado utilizando una cola que en el proceso de la pila, la búsqueda se ha de dar marcha atrás a partir de un deadend y tomar otro camino – estos backtrack puntos que se pueden poner en una cola, y varios de los procesos de la onu-cola de los puntos y probar otros caminos.

  7. 1

    Calcular así:

    x = 1 - 1/3 + 1/5 - 1/7 + 1/9  (... etc as far as possible.)
    PI = x * 4

    Tienes Pi !!!

    Este es el método más simple que yo sepa.

    El valor de PI lentamente converge al valor real de Pi (3.141592165……). Si usted repetir más veces, mejor.

  8. 1

    Aquí un buen enfoque (desde la principal entrada de la Wikipedia sobre la pi); converge mucho más rápido que la simple fórmula se discutió anteriormente, y es muy susceptible de una solución recursiva si su intención es la de buscar la recursividad como un ejercicio de aprendizaje. (Asumiendo que está después de la experiencia de aprendizaje, no le voy a dar cualquier código real.)

    La fórmula subyacente es el mismo que el anterior, pero este enfoque promedios de las sumas parciales para acelerar la convergencia.

    Definir dos parámetros de la función, pie(h, w), tal que:

    pie(0,1) = 4/1
    pie(0,2) = 4/1 - 4/3
    pie(0,3) = 4/1 - 4/3 + 4/5
    pie(0,4) = 4/1 - 4/3 + 4/5 - 4/7
    ... and so on

    Así su primera oportunidad para explorar la recursividad es el código que «horizontal» de la computación como el «ancho» del parámetro aumenta (por la «altura» de cero).

    A continuación, agregue la segunda dimensión con esta fórmula:

    pie(h, w) = (pie(h-1,w) + pie(h-1,w+1)) / 2

    que se utiliza, por supuesto, sólo para valores de h mayor que cero.

    La cosa buena acerca de este algoritmo es que puede burlarse de ella con una hoja de cálculo para verificar el código a medida que explora los resultados producidos por el cada vez mayor parámetros. En el momento de calcular el pastel(10,10), tendrá un valor aproximado de pi que es lo suficientemente bueno para la mayoría de los fines de ingeniería.

  9. 1
    Enumerable.Range(0, 100000000).Aggregate(0d, (tot, next) => tot += Math.Pow(-1d, next)/(2*next + 1)*4)
    • De hecho, si se intenta con 100000000, le da la espalda 3,14159264358933, lo cual es incorrecto. Si sacan un 0 (10000000), le da la espalda 3,14159265358979 que está bien. El ataque de los de punto flotante de operación roundup de nuevo?
  10. 1
    using System;
    
    namespace Strings
    {
        class Program
        {
            static void Main(string[] args)
            {
    
    /*          decimal pie = 1; 
                decimal e = -1;
    */
                var stopwatch = new System.Diagnostics.Stopwatch();
                stopwatch.Start(); //added this nice stopwatch start routine 
    
      //leibniz formula in C# - code written completely by Todd Mandell 2014
    /*
                for (decimal f = (e += 2); f < 1000001; f++)
                {
                     e += 2;
                     pie -= 1 /e;
                     e += 2;
                     pie += 1 /e;
                     Console.WriteLine(pie * 4);
                }
    
                     decimal finalDisplayString = (pie * 4);
                     Console.WriteLine("pie = {0}", finalDisplayString);
                     Console.WriteLine("Accuracy resulting from approximately {0} steps", e/4); 
    */
    
    //Nilakantha formula - code written completely by Todd Mandell 2014
    //π = 3 + 4/(2*3*4) - 4/(4*5*6) + 4/(6*7*8) - 4/(8*9*10) + 4/(10*11*12) - (4/(12*13*14) etc
    
                decimal pie = 0;
                decimal a = 2;
                decimal b = 3;
                decimal c = 4;
                decimal e = 1;
    
                for (decimal f = (e += 1); f < 100000; f++) 
                //Increase f where "f < 100000" to increase number of steps
                {
    
                    pie += 4 / (a * b * c);
    
                    a += 2;
                    b += 2;
                    c += 2;
    
                    pie -= 4 / (a * b * c);
    
                    a += 2;
                    b += 2;
                    c += 2;
    
                    e += 1;
                }
    
                decimal finalDisplayString = (pie + 3);
                Console.WriteLine("pie = {0}", finalDisplayString);
                Console.WriteLine("Accuracy resulting from {0} steps", e); 
    
                stopwatch.Stop();
                TimeSpan ts = stopwatch.Elapsed;
                Console.WriteLine("Calc Time {0}", ts); 
    
                Console.ReadLine();
    
             }
         }
     }
  11. 1
        public static string PiNumberFinder(int digitNumber)
        {
            string piNumber = "3,";
            int dividedBy = 11080585;
            int divisor = 78256779;
            int result;
    
            for (int i = 0; i < digitNumber; i++)
            {
                if (dividedBy < divisor)
                    dividedBy *= 10;
    
                result = dividedBy / divisor;
    
                string resultString = result.ToString();
                piNumber += resultString;
    
                dividedBy = dividedBy - divisor * result;
            }
    
            return piNumber;
        }
  12. 0

    En cualquier escenario de producción, me obligaría a usted para buscar el valor, para el número deseado de puntos decimales, y la almacenan como una ‘const’ en algún lugar de su clases pueden llegar a ella.

    (a menos que usted está escribiendo científica ‘Pi’ software específico…)

    • Un comentario sobre la downvote me ayuda a comprender lo que hice mal. Ahora tengo que adivinar. Tal vez usted es un descontento equipo científico que no aprecio mi enfoque pragmático. No se tiene en cuenta para contestar el espíritu de la pregunta «¿cómo ir sobre ella desde un punto de vista del aprendizaje». Aunque yo debate que porque mi respuesta es la más eficiente solución.
    • La pregunta estaba pidiendo un algoritmo para encontrar el pi, no cómo utilizar el valor de pi
  13. 0

    Respecto…

    … cómo ir sobre ella desde un punto de vista del aprendizaje.

    Que están tratando de aprender a programar métodos científicos? o para producir software de producción? Espero que la comunidad ve esto como una pregunta válida y no un ser quisquilloso.

    En cualquier caso, creo que la escritura de su propia Pi es un problema resuelto. Dmitry mostró la Matemática.PI’ constante ya. El ataque de otro problema en el mismo espacio! Ir genéricos de Newton aproximaciones o algo resbaladizo.

  14. 0

    @Thomas Kammeyer:

    Nota que Atan(1.0) es muy a menudo codificados, por lo que 4*Atan(1.0) no es realmente un ‘algoritmo’ si usted está llamando a una biblioteca de la función Atan (un muy pocos ya se ha sugerido, de hecho, proceder a la sustitución de Atan(x) por una serie (o infinito de producto) para que, luego de evaluar en x=1.

    También, son muy pocos los casos donde se había necesidad de pi en más precisión que un par de decenas de bits (que puede ser fácilmente modificable!). He trabajado en aplicaciones en las matemáticas, donde, para calcular (bastante complicado) los objetos matemáticos (que fueron polinomio con coeficientes enteros), tuve que hacer aritmética reales y números complejos (incluidos los informáticos pi) con una precisión de hasta un par de millones de bits… pero esto no es muy frecuente «en la vida real’ 🙂

    Puede buscar en el siguiente ejemplo código.

  15. 0

    Me gusta este papel, que explica cómo calcular el π basado en una expansión en series de Taylor para Arcotangente.

    El trabajo comienza con la simple suposición de que

    Atan(1) = π/4 radianes

    Atan(x) puede ser de forma iterativa estimado con la serie de Taylor

    atan(x) = x – x^3/3 + x^5/5 – x^7/7 + x^9/9…

    El artículo señala por qué esto no es particularmente eficiente y se va a hacer una serie de lógicas refinamientos en la técnica. También ofrecen un programa de ejemplo que calcula π de unos cuantos miles de dígitos, que se completa con el código fuente, incluyendo la infinita precisión rutinas matemáticas requeridas.

    • Y mientras estás allí, echa un vistazo a impresionante fractal generador 🙂
  16. 0

    Primer lugar, tenga en cuenta que C# puede utilizar las Matemáticas.PI campo de la .NET framework:

    https://msdn.microsoft.com/en-us/library/system.math.pi(v=vs 110).aspx

    La característica interesante aquí es que es un doble de la precisión que usted puede utilizar, o comparar con los resultados calculados. Las pestañas en la URL similares constantes para C++, F# y Visual Basic.

    Para calcular más lugares, usted puede escribir su propio extendida de precisión código. Uno que es rápido de código y razonablemente fácil y rápida para el programa es:

    Pi = 4 * [4 * arctg (1/5) – arctg (1/239)]

    Esta fórmula y muchos otros, incluyendo algunos que convergen en increíblemente rápido de las tasas, como la de 50 dígitos cada término, son de Wolfram:

    Wolfram Pi Fórmulas

  17. 0

    PI (π) se puede calcular mediante serie infinita. He aquí dos ejemplos:

    Gregorio-Leibniz Serie:

    π/4 = 1 – 1/3 + 1/5 – 1/7 + 1/9 – …

    C# método :

    public static decimal GregoryLeibnizGetPI(int n)
    {
        decimal sum = 0;
        decimal temp = 0;
        for (int i = 0; i < n; i++)
        {
            temp = 4m / (1 + 2 * i);
            sum += i % 2 == 0 ? temp : -temp;
        }
        return sum;
    }

    Nilakantha Serie:

    π = 3 + 4 /(2x3x4) – 4 /(4x5x6) + 4 /(6x7x8) – 4 /(8x9x10) + …

    C# método:

    public static decimal NilakanthaGetPI(int n)
    {
        decimal sum = 0;
        decimal temp = 0;
        decimal a = 2, b = 3, c = 4;
        for (int i = 0; i < n; i++)
        {
            temp = 4 / (a * b * c);
            sum += i % 2 == 0 ? temp : -temp;
            a += 2; b += 2; c += 2;
        }
        return 3 + sum;
    }

    El parámetro de entrada n para ambas funciones representa el número de la iteración.

    La Nilakantha Serie en comparación con Gregory-Leibniz de la Serie converge más rápidamente. Los métodos pueden ser probados con el siguiente código:

    static void Main(string[] args)
    {
        const decimal pi = 3.1415926535897932384626433832m;
        Console.WriteLine($"PI = {pi}");
    
        //Nilakantha Series
        int iterationsN = 100;
        decimal nilakanthaPI = NilakanthaGetPI(iterationsN);
        decimal CalcErrorNilakantha = pi - nilakanthaPI;
        Console.WriteLine($"\nNilakantha Series -> PI = {nilakanthaPI}");
        Console.WriteLine($"Calculation error = {CalcErrorNilakantha}");
        int numDecNilakantha = pi.ToString().Zip(nilakanthaPI.ToString(), (x, y) => x == y).TakeWhile(x => x).Count() - 2;
        Console.WriteLine($"Number of correct decimals = {numDecNilakantha}");
        Console.WriteLine($"Number of iterations = {iterationsN}");
    
        //Gregory-Leibniz Series
        int iterationsGL = 1000000;
        decimal GregoryLeibnizPI = GregoryLeibnizGetPI(iterationsGL);
        decimal CalcErrorGregoryLeibniz = pi - GregoryLeibnizPI;
        Console.WriteLine($"\nGregory-Leibniz Series -> PI = {GregoryLeibnizPI}");
        Console.WriteLine($"Calculation error = {CalcErrorGregoryLeibniz}");
        int numDecGregoryLeibniz = pi.ToString().Zip(GregoryLeibnizPI.ToString(), (x, y) => x == y).TakeWhile(x => x).Count() - 2;
        Console.WriteLine($"Number of correct decimals = {numDecGregoryLeibniz}");
        Console.WriteLine($"Number of iterations = {iterationsGL}");
    
        Console.ReadKey();
    }

    El siguiente resultado muestra que Nilakantha Serie vuelve seis correcta decimales de PI con cien iteraciones mientras que Gregory-Leibniz Serie devuelve cinco corregir los decimales de PI, con un millón de iteraciones:

    ¿Cómo puedo calcular PI en C#?

    Mi código puede ser probado >> aquí

  18. 0

    Aquí es una buena manera:
    Calcular una serie de 1/x^2 para x desde 1 a lo que quiera – el número más alto – la mejor tarta de resultado. Multiplicar el resultado por 6 y a la función sqrt().
    Aquí está el código en c# (sólo principal):

    static void Main(string[] args)
        {
            double counter = 0;
            for (double i = 1; i < 1000000; i++)
            {
    
                counter = counter + (1 / (Math.Pow(i, 2)));
    
            }
            counter = counter * 6;
            counter = Math.Sqrt(counter);
            Console.WriteLine(counter);
        }
  19. -8
    public double PI = 22.0 / 7.0;
    • PI == 3.14159… 22.0 / 7.0 == 3.14285… Apenas una respuesta precisa.
    • -1 la pregunta estaba pidiendo un método para fines educativos, no es un valor, y 22/7 es una mala aproximación, en cualquier caso.

Dejar respuesta

Please enter your comment!
Please enter your name here