
ex serpiente
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n,i,ele;
n=5;
ele=pow(n,2);
printf("%d",ele);
return 0;
}
la salida es 24
.
Estoy usando GNU/GCC en Code::Blocks.
¿Qué está pasando?
Sé que el pow
función devuelve un double
pero 25
se ajusta a un tipo int, entonces, ¿por qué este código imprime un 24
en lugar de un 25
? Si n=4; n=6; n=3; n=2;
el código funciona, pero con los cinco no.

pablomckenzie
Esto es lo que puede estar sucediendo aquí. Debería poder confirmar esto observando la implementación de su compilador del pow
función:
Suponiendo que tiene los #include correctos (todas las respuestas anteriores y los comentarios sobre esto son correctos, no tome la #include
archivos por sentado), el prototipo para el estándar pow
la funcion es esta:
double pow(double, double);
y estas llamando pow
Me gusta esto:
pow(5,2);
Él pow
La función pasa por un algoritmo (probablemente usando logaritmos), por lo tanto, usa funciones y valores de coma flotante para calcular el valor de la potencia.
Él pow
función no pasa por un ingenuo “multiplicar el valor de xa total de n veces”, ya que también tiene que calcular pow
usando exponentes fraccionarios, y no puedes calcular potencias fraccionarias de esa manera.
Entonces, lo más probable es que el cálculo de pow
el uso de los parámetros 5 y 2 resultó en un ligero error de redondeo. Cuando te asignan a un int
truncaste el valor fraccionario, dando así 24.
Si está utilizando números enteros, también podría escribir su propio “intpow” o una función similar que simplemente multiplique el valor la cantidad de veces requerida. Los beneficios de esto son:
-
No entrará en la situación en la que puede obtener errores de redondeo sutiles usando pow
.
-
Su intpow
Lo más probable es que la función se ejecute más rápido que una llamada equivalente a pow
.
Desea un resultado int de una función destinada a dobles.
Tal vez deberías usar
ele=(int)(0.5 + pow(n,2));
/* ^ ^ */
/* casting and rounding */
La aritmética de punto flotante no es exacta.
Aunque los valores pequeños se pueden sumar y restar exactamente, el pow()
La función normalmente funciona multiplicando logaritmos, por lo que incluso si las entradas son exactas, el resultado no lo es. Asignando a int
siempre se trunca, por lo que si la inexactitud es negativa, obtendrá 24 en lugar de 25.
La moraleja de esta historia es usar operaciones con números enteros sobre números enteros, y desconfiar de <math.h>
funciones cuando los argumentos reales se van a promover o truncar. Es lamentable que GCC no avise a menos que agregue -Wfloat-conversion
(no está en -Wall -Wextra
probablemente porque hay muchos casos en los que se prevé y desea dicha conversión).
Para potencias enteras, siempre es más seguro y rápido usar la multiplicación (división si es negativa) en lugar de pow()
– ¡reserva este último para donde lo necesites! Sin embargo, tenga en cuenta el riesgo de desbordamiento.

Jayesh Bhoi
Cuando usa pow con variables, su resultado es double
. Asignación a un int
lo trunca.
Entonces puede evitar este error asignando el resultado de pow
para double
o float
variable.
Así que básicamente
se traduce a exp(log(x) * y)
que producirá un resultado que no es precisamente el mismo que x^y
– solo una aproximación cercana como un valor de coma flotante. Así por ejemplo 5^2
se convertirá 24.9999996
o 25.00002
Si no lo hace #include <math.h>
entonces el compilador no conoce los tipos de argumentos a pow()
que son ambos double
no int
— entonces obtienes un resultado indefinido. Obtienes 24, obtengo 16418.
Puede intentar tomar el valor de retorno de
pow
en unfloat
odouble
variable, luego intente encasillarla enint
. A ver si eso también produce24
o la respuesta correcta25
– No te preocupes niño
5 de septiembre de 2014 a las 4:25
@exsnake – El
pow
función no hace simplemente una multiplicación de 5 * 5. El resultado final es probablemente24.9999999
o resultado similar. Élpow
La función probablemente usa logaritmos para calcular el resultado, ya que también tiene que manejar potencias fraccionarias. Para confirmar, mire la implementación de su compilador depow
.– Paul McKenzie
5 de septiembre de 2014 a las 4:35
Debe aclarar qué sistema operativo está utilizando, ya que es casi seguro que se trata de un error en su implementación de la parte matemática de la biblioteca estándar. Supongo que estás usando mingw con MSVCRT en Windows…
– R.. GitHub DEJA DE AYUDAR A ICE
5 de septiembre de 2014 a las 4:55
¿Puedes compartir la salida de
printf("%.25lf\n", pow(n,2));
en su implementación donden=5
?-Mohit Jain
5 de septiembre de 2014 a las 5:08
Un bien
pow(n,2)
devolvería resultados exactamente correctos. C no especifica cómo buenopow()
debe ser.– chux – Reincorporar a Monica
5 sep 2014 a las 14:35