2011-06-19 11 views
40

Estoy haciendo un programa que se aproxima a PI y estoy tratando de usar mucho tiempo, pero no está funcionando. Este es el códigoCómo imprimir longif largo

#include<stdio.h> 
#include<math.h> 
typedef long long num; 
main(){ 
    num pi; 
    pi=0; 
    num e, n; 
    scanf("%d", &n); 
    for(e=0; 1;e++){ 
     pi += ((pow((-1.0),e))/(2.0*e+1.0)); 
     if(e%n==0) 
     printf("%15lld -> %1.16lld\n",e, 4*pi); 
     //printf("%lld\n",4*pi); 
    } 
} 
+1

Supongo que su problema es más con el 'scanf' que con el' printf'. – Nemo

+0

'pow ((- 1.0), e)' sería mucho mejor expresado como 'e% 2? 1: -1' –

Respuesta

-1

En primer lugar,% d es un int

Así %1.16lld no tiene sentido, porque% d es un número entero

Eso typedef lo hace, también es innecesaria , use el tipo al frente, crea un código mucho más legible.

Lo que se quiere utilizar es el double, para el cálculo de Pi y luego usando %f o %1.16f.

+0

No es realmente "ilegal" ... es específico de MSVC, creo. – Mehrdad

+2

@Mehrdad ¿Desde cuándo los números enteros tienen puntos decimales? –

+6

Incorrecto. Lea la [especificación para printf] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html). '% lld' es exactamente cómo se imprime un' long long'. (Por supuesto, el '1.16' puede no hacer lo que quieras ... Pero es perfectamente válido. Significa usar un ancho de campo mínimo de 1 e imprimir 16 dígitos.) – Nemo

53

%lld es la forma estándar C99, pero eso no funciona en el compilador que estoy usando (mingw32-gcc v4.6.0). La forma de hacerlo en este compilador es: %I64d

Así que trate esto:

if(e%n==0)printf("%15I64d -> %1.16I64d\n",e, 4*pi); 

y

scanf("%I64d", &n); 

La única forma que conozco para hacer esto de una manera completamente portátil es use las definiciones en <inttypes.h>.

En su caso, se vería así:

scanf("%"SCNd64"", &n); 
//...  
if(e%n==0)printf("%15"PRId64" -> %1.16"PRId64"\n",e, 4*pi); 

lo que realmente es muy feo ... pero por lo menos es portátil.

+7

No es tu compilador sino tu biblioteca de C el responsable aquí. Está utilizando la biblioteca Microsoft C, que no admite '% lld', que es una característica C99 (aunque también lo es' inttypes.h'). – caf

+0

Para ser más específico, es msvcrt.dll, que es la versión antigua (circa 1998) de la biblioteca estándar C que se escribió originalmente para VC++ 6.0 y se envía con Windows para fines de compatibilidad con versiones anteriores. MinGW usa esa versión antigua, porque es la única que sale de la caja con Windows. Pero el tiempo de ejecución moderno de VC++ maneja '% lld' correctamente. –

+0

Visual C++ 2013 parece ser compatible con el elemento de formato% lld – user1741137

2
  • Su declaración scanf() necesita utilizar %lld también.
  • Su bucle no tiene una condición de terminación.
  • Hay demasiados paréntesis, y muy pocos espacios en la expresión

    pi += pow(-1.0, e)/(2.0*e + 1.0); 
    
  • Se agrega una en la primera iteración del bucle, y posteriormente a cero el valor de 'pi'; esto no cambia mucho el valor.
  • Debe usar un tipo de devolución explícita de int para main().
  • En general, es mejor especificar int main(void) cuando ignora sus argumentos, aunque eso es menos una declaración categórica que el resto.
  • No me gusta la licencia explícita otorgada en C99 para omitir la devolución al final de main() y no la uso yo mismo; Escribo return 0; para ser explícito.

Creo que todo el algoritmo es dudoso cuando se escribe usando long long; el tipo de datos probablemente debería ser más como long double (con %Lf para el formato scanf(), y quizás %19.16Lf para los formatos printf().

0
double pi = 2 * acos(0.0); 
    int n; 
    scanf("%d",&n); //precision with which you want the value of pi 
    printf("%.*lf\n",n,pi); 
+1

Si bien este fragmento de código puede ser la solución, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y esas personas podrían no conocer los motivos de su sugerencia de código –