2010-08-16 17 views
6

Escribí un programa para calcular enésima raíz de un número hasta 2 decimales. por ejemplo, la cuarta raíz de 81 es 3., la tercera raíz de 125 es 5. Está funcionando bien, excepto la segunda raíz de 4. Da la salida 1.99 en lugar de 2. Aquí está el código.enésima raíz de un número

#include<stdio.h> 
int main(int argc, char **argv) 
{ 
    double root1(int,int); 
    int n; 
    int num1; 
    double root; 
    printf("\n\n-----------This is the programme to find the nth root of a number-----------\n\n"); 
    printf("Enter a nuber greater then 1 : "); 
    scanf("%d",&num1); 
    if(num1>1) 
    { 
     printf("Enter the value for 'n'(the root to be calculated) : "); 
     scanf("%d",&n); 
     root = root1(num1,n); 
     printf("%d th Root of %d is %f\n\n", n,num1,root); 
    } 
    else 
     printf("wrong entry"); 
    return 0; 
} 

double root1(int a, int b) 
{ 
    int j; 
    double i,k; 
    double incre = 0.01; 
    for(i=1; i<=a; i = i+incre) 
    { 
     for(j=0;j<b;j++) 
     { 
      k=k*i; 
     } 
     if(a<k) 
     { 
      return(i-incre); 
      break; 
     } 
     else 
      k=1; 
    } 
} 

Lo he intentado durante horas, pero no puedo rectificarlo. ¿alguien puede depurar esto? Estaré muy agradecido.

+0

Utilice el botón de código: ayuda a otros a leer su código. –

+0

Disculpe las molestias. Soy nuevo aquí. La próxima vez me ocuparé de esto. – narayanpatra

+0

preguntas editadas. en lugar de 3, tiene hasta 2 lugares decimales. – narayanpatra

Respuesta

5

La respuesta, como ocurre con la mayoría de los problemas de coma flotante, es que C funciona con una precisión limitada. Y las carrozas son binarias. No pueden representar exactamente el número decimal 1.99; es probable que sea un valor cercano al 1.990000000023.....

enlace estándar para estos problemas: What Every Computer Scientist Should Know About Floating-Point

Hay afortunadamente una solución fácil (pero no es perfecto!). Encuentra la raíz de (num * 10000.0), usando incrementos de uno. Esto será, por supuesto, 100 veces la raíz que realmente deseas. Por lo tanto, los dos últimos dígitos son los "lugares decimales" que quería. Encontrará que la raíz de 40000.0 es precisamente 200.0. Esto funciona porque 1.0 se puede representar perfectamente.

El precio que paga por la precisión en ese extremo es que lo pierde en el otro extremo: multiplicar por 10000 significa que obtendrá una pérdida de precisión con números más altos. Las soluciones fáciles rara vez vienen sin inconvenientes, lo siento.

+0

pero por qué no va a subir a 2. Mi condición para el descanso es una narayanpatra

+2

Lo mismo. No puede representar el número '0.01' tampoco. Será algo como be '0.009999999999984 ...'. Por lo tanto, 0.01 + 0.01 será '0.019999999999968 ...'. Y 0.01 + 0.01 + 0.01 + 0.01 (veces 199) causará 198 errores de redondeo. – MSalters

+0

Gracias amigo. Toda esta información es muy útil para mí. – narayanpatra

6

Esto se debe a que las computadoras no pueden manejar correctamente los números reales.

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

+3

Más específicamente, las computadoras no pueden manejar * precisión infinita *. Todos los objetos, incluidos todos los números, que incluyen todos los números de coma flotante, están representados por un conjunto finito de bytes. –

+3

@Loadmaster: aún más específicamente: las computadoras manejan la precisión indefinida como lo hacen los humanos: simbólicamente. – Richard

2

Bueno, si quieres 0,01 exactitud, es necesario intensificar 0,005 o menos, y luego realizar el redondeo. La mejor manera es simplemente usar pow (num1, 1/n) :-)

0

Los doblajes no necesariamente representan los números de coma flotante con precisión. Trate de usar un tipo de datos decimal en su lugar (si c tiene esa idea, lo siento, no puedo recordar). C# tiene decimal, Java tiene clases BigDecimal para representar números de punto flotante con precisión.

1

lo que dijo MSalters. intente hacer incre más pequeño para ver cómo el valor se acerca gradualmente a 2.0. Es posible que desee tener una mayor precisión "interna" (es decir, incre) que lo que devuelve, y redondee el resultado interno a, por ejemplo, 2 dígitos. De esta manera puede cubrir esos problemas de redondeo (pero es solo una sospecha no comprobada)

+0

No funciona, de hecho se acumularán más errores de redondeo. Actualmente tiene 199 errores de redondeo, todos en 1up. Disminuir el incremento a 0.001 significa que tendrá errores de redondeo de 1999, aún en 1 arriba. Ahora 1up de 0.001 es un poco más pequeño, pero apenas avanza. Además, está agregando 1998 veces en lugar de 198 veces, lo que significa que tiene más errores de redondeo pero más pequeños. – MSalters

0

Un valor más pequeño "incre" debería funcionar, he usado 0,001 y 2,00 para regresar root1 la raíz cuadrada de 4.

Además, si desea que la respuesta que se mostrará a 2 decimales, utilice% .2f cuando imprimes la raíz.

2

tomar k = 1;

#include<stdio.h> 
int main(int argc, char **argv) 
{ 
    double root1(int,int); 
    int n; 
    int num1; 
    double root; 
    printf("\n\n-----------This is the programme to find the nth root of a number-----------\n\n"); 
    printf("Enter a nuber greater then 1 : "); 
    scanf("%d",&num1); 
    if(num1>1) 
    { 
     printf("Enter the value for 'n'(the root to be calculated) : "); 
     scanf("%d",&n); 
     root = root1(num1,n); 
     printf("%d th Root of %d is %f\n\n", n,num1,root); 
    } 
    else 
     printf("wrong entry"); 
    return 0; 
} 

double root1(int a, int b) 
{ 
    int j; 
    double i,k=1; 
    double incre = 0.01; 
    for(i=1; i<=a; i = i+incre) 
    { 
     for(j=0;j<b;j++) 
     { 
      k=k*i; 
     } 
     if(a<k) 
     { 
      return(i-incre); 
      break; 
     } 
     else 
      k=1; 
    } 
} 
0
#include <iostream> 
#include<math.h> 
using namespace std; 
int main() 
{ 
double n,m; 
cin>>n; 
cin>>m; 
m= pow(m, (1/n)); 
cout<<m; 
return 0; 
} 

Por qué escribir estas enormes code.This funciona perfectamente hasta que cambie doble a int.

+0

¿Estás tratando de ayudar al OP o insultarlo? –

Cuestiones relacionadas