I am having some problems with pow()
function in C. When ever run this code, 153
as input, the sum evaluates to 152
. However if I dont use pow()
function and instead use a for
loop to get the value of Nn, the sum evaluates to 153
. Can anyone help please explain me this difference?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int main(void) {
unsigned int i, n, sum = 0, N, a = 1, j;
char num[100], x[2] = { 0 };
printf("Determining an armstrong number\n\n"
"Enter a number: ");
fflush(stdin);
gets(num);
n = strlen(num);
for (i = 0; i < n; i++) {
a = 1;
x[0] = num[i];
N = atoi(x);
/* for (j = 1; j <= n; j++)
a *= N;
*/
sum += pow(N, n);
}
n = atoi(num);
if (sum == n)
printf("\nIt is an Armstrong number!\n");
else
printf("\nIt is not an Armstrong number!\n");
return 0;
}
Your C implementation, including its math library, has a bad implementation of
pow
that returns inaccurate results. (A goodpow
implementation returns an exact result when the mathematical result is exactly representable in the floating-point format.) For example, forpow(7, 2)
, yourpow
may be returning a value slightly under 49. When this is converted to anunsigned int
(in the addition tosum
), it is truncated, resulting in 48.To work around this defect in your library, do not use
pow
for integer arithmetic. Write your own integer arithmetic to get the result you desire. In some circumstances, usinground(pow(N, n))
may suffice, but there are considerations of the range of values for which this will work (wide integers may be able to represent integers thatdouble
cannot) and sometimes performance. (Another workaround is to get a better C implementation.)