I have seen various answer here that depicts Strange behavior of pow
function in C.
But I Have something different to ask here.
In the below code I have initialized int x = pow(10,2)
and int y = pow(10,n)
(int n = 2)
.
In first case it when I print the result it shows 100
and in the other case it comes out to be 99
.
I know that pow
returns double
and it gets truncated on storing in int
, but I want to ask why the output comes to be different.
CODE1
#include<stdio.h>
#include<math.h>
int main()
{
int n = 2;
int x;
int y;
x = pow(10,2); //Printing Gives Output 100
y = pow(10,n); //Printing Gives Output 99
printf("%d %d" , x , y);
}
Output : 100 99
Why is the output coming out to be different. ?
My gcc version is 4.9.2
Update :
Code 2
int main()
{
int n = 2;
int x;
int y;
x = pow(10,2); //Printing Gives Output 100
y = pow(10,n); //Printing Gives Output 99
double k = pow(10,2);
double l = pow(10,n);
printf("%d %d\n" , x , y);
printf("%f %f\n" , k , l);
}
Output : 100 99
100.000000 100.000000
Update 2 Assembly Instructions FOR CODE1
Generated Assembly Instructions GCC 4.9.2 using gcc -S -masm=intel
:
.LC1:
.ascii "%d %d\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
push ebp
mov ebp, esp
and esp, -16
sub esp, 48
call ___main
mov DWORD PTR [esp+44], 2
mov DWORD PTR [esp+40], 100 //Concerned Line
fild DWORD PTR [esp+44]
fstp QWORD PTR [esp+8]
fld QWORD PTR LC0
fstp QWORD PTR [esp]
call _pow //Concerned Line
fnstcw WORD PTR [esp+30]
movzx eax, WORD PTR [esp+30]
mov ah, 12
mov WORD PTR [esp+28], ax
fldcw WORD PTR [esp+28]
fistp DWORD PTR [esp+36]
fldcw WORD PTR [esp+30]
mov eax, DWORD PTR [esp+36]
mov DWORD PTR [esp+8], eax
mov eax, DWORD PTR [esp+40]
mov DWORD PTR [esp+4], eax
mov DWORD PTR [esp], OFFSET FLAT:LC1
call _printf
leave
ret
.section .rdata,"dr"
.align 8
LC0:
.long 0
.long 1076101120
.ident "GCC: (tdm-1) 4.9.2"
.def _pow; .scl 2; .type 32; .endef
.def _printf; .scl 2; .type 32; .endef
#include<math.h>
. – Chickamaugadouble
values and see any differences? Just as an experiment. – Bioscopepow
corresponding to your gcc version, duplicate it and run with the debugger to see what's going on. – Bioscopepow
and links to it; the library itself is the likely cause of rounding errors. – Jerboa__gnu_cxx::__promote_2<int, int, __gnu_cxx::__promote<int, std::__is_integer<int>::__value>::__type, __gnu_cxx::__promote<int, std::__is_integer<int>::__value>::__type>::__type std::pow<int, int>(int, int)
mean is roughly that the implementation calls a template function and converts (promotes) your arguments from their original type to the type required by thestd::pow<int, int>(int, int)
. It isn't immediately obvious why the conversions are deemed necessary. – Straightoutg++
as the compiler, or possibly usinggcc
but specifying a file name with an extension like.cpp
or.cxx
— or perhaps.C
(upper-case letter C) as the extension, andgcc
is interpreting that as a C++ source file and running appropriate compiler phases for C++ instead of C. – Straightoutgcc -S
. – Straightout-fno-builtin
will disable. Also see log(10.0) can compile but log(0.0) cannot? and Inconsistent strcmp() return value when passing strings as pointers or as literals – Bisset