2010-11-05 13 views
5

Estoy escribiendo una función que calcula el valor de PI y lo devuelve como un doble. Hasta aquí todo bien. Pero una vez que la función llega a 14 dígitos después del lugar decimal, no puede contener más. Supongo que esto se debe a la precisión limitada del doble. ¿Qué debo hacer para seguir obteniendo más números después del lugar decimal?C# Alta precisión doble

Respuesta

16

No lo haría en punto flotante en absoluto.

Recordemos que el algoritmo es:

(1 + 1/(2 * 1 + 1)) * 
(1 + 2/(2 * 2 + 1)) * 
(1 + 3/(2 * 3 + 1)) * 
(1 + 4/(2 * 4 + 1)) * 
(1 + 5/(2 * 5 + 1)) * 
(1 + 6/(2 * 6 + 1)) * 
(1 + 7/(2 * 7 + 1)) * ... 

Cada etapa en el camino a calcular una fracción. ¿Por qué no mantener simplemente esa fracción en su forma de numerador/denominador? La fracción desea calcular es:

(4/3) * 
(7/5) * 
(10/7) * 
(13/9) * ... 

que está a 4 * 7 * 10 * 13 ... en la parte superior y 3 * 5 * 7 * 9 en la parte inferior.

Obtenga una clase BigInteger (una se incluye con el framework 4.0 en System.Numerics) y podrá calcular fácilmente el numerador y el denominador tan grandes como desee. Entonces solo tienes el problema de convertir el cociente a decimal. Bueno, eso es bastante fácil. Presumiblemente sabes cómo hacer la división larga. Simplemente implemente un algoritmo de división larga en el numerador y el denominador que escupe la cantidad deseada de dígitos.

8

¿Cuánta precisión necesita?

Usando decimal le dará aproximadamente 28 cifras decimales:

decimal pi = 3.14159265358979323846264338327950288419716939937510m; 
Console.WriteLine(pi); // 3.1415926535897932384626433833 

Si eso no es suficiente para usted, entonces tendrá que buscar algún tipo de aplicación BigDecimal, o mirar otras técnicas para realizar el cálculo .

0

Sí, es porque la precisión limitada del doble. Hay varias formas diferentes de calcular los dígitos de pi. Sugeriría que le preguntes a tu motor de búsqueda favorito, "cómo calcular los dígitos de pi".

0

Puede utilizar el tipo J # BigDecimal, como se sugiere en this answer.

1

Existen varias bibliotecas que le permiten trabajar con precisión arbitraria. Uno es W3b.sine, pero varios otros se describen en wikipedia.

1

Pruebe decimal en lugar de doble. No puede almacenar números tan grandes como el doble, pero creo que tiene una mayor precisión después del decimal. Si necesita más, probablemente tendrá que usar un String.

+0

No usaría una cadena; tendría gastos extras de conversión a/desde números. – JLWarlow

+0

Sí, pero si necesita más de 28 dígitos de precisión, no hay tipos de datos incorporados para eso. IIRC C# tiene algún tipo de clase para valores con (prácticamente) tamaño ilimitado, y estoy bastante seguro de que los almacenará internamente como una cadena ... – user472875

+0

... o una matriz de bytes. –

Cuestiones relacionadas