#1651 Problem with pow() function when calculating power of 10

WSL
closed
nobody
None
rejected
User_Error
2013-01-25
2012-06-21
Chirayu Chiripal
No

My program is calculating the log=log10(num) and then using pow(10,log-1) to
get the power of 10 one less than its log.

Here is the code:
// Sandbox.c
#include<stdio.h>
#include<math.h>
int main()
{ int t,n,log,po;
printf(\"\\nTest Cases:\");
scanf(\"%d\",&t);
while(t--)
{ printf(\"\\nNumber:\");
scanf(\"%d\",&n);
log=log10(n);
printf(\"\\nlog=%d\\n\",log);
po=pow(10,log);
printf(\"pow(10,log)=%d\\n\",po);
po=pow(10,log-1);
printf(\"pow(10,log-1)=%d\\n\",po);
po=pow(10,log);
printf(\"pow(10,log)=%d\\n\",po);
po=pow(10,log)/10;
printf(\"pow(10,log)/10=%d\\n\\n\",po);
}
return 0;
}

OUTPUT (Expected):

Test Cases:2
Number:1020
log=3
pow(10,log)=1000
pow(10,log-1)=100
pow(10,log)=1000
pow(10,log)/10=100

Number:10230
log=4
pow(10,log)=10000
pow(10,log-1)=1000
pow(10,log)=10000
pow(10,log)/10=1000

OUTPUT (Actual):

Test Cases:2
Number:1020
log=3
pow(10,log)=1000
pow(10,log-1)=99 // Problem Here
pow(10,log)=1000
pow(10,log)/10=100

Number:10230
log=4
pow(10,log)=10000
pow(10,log-1)=1000
pow(10,log)=9999 // Problem Here
pow(10,log)/10=999 // Problem Here

Compiler Options Used in CMD:

>gcc sandbox.c -o sand

>sand

Version shown by \"gcc -v\":

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.6.2/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.6.2/configure
--enable-languages=c,c++,ada,fortran,obj
c,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared
--enable-libgo
mp --disable-win32-registry --enable-libstdcxx-debug
--enable-version-specific-r
untime-libs --build=mingw32 --prefix=/mingw
Thread model: win32
gcc version 4.6.2 (GCC)

System Specs:
Win 7 Home Premium 64 bit
Intel Core i7-2670QM @ 2.20 GHz

Works fine when run on IDEONE in C(gcc-4.3.4)
http://ideone.com/cQRrY

Discussion

  • Screenshot of the bug

     
    Attachments
  • Also reported on GCC Bugzilla:
    http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53738

    They said "Works for me correctly on linux. In fact there is nothing GCC can do since pow is not provided by GCC but rather who ever provides your libc."

     
  • Then i updated my GCC version to 4.7.0 but the problem was not resolved.

    GCC Version Now:
    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.7.0/lto-wrapper.exe
    Target: mingw32
    Configured with: ../gcc-4.7.0/configure --enable-languages=c,c++,ada,fortran,obj
    c,obj-c++ --disable-sjlj-exceptions --with-dwarf2 --enable-shared --enable-libgo
    mp --disable-win32-registry --enable-libstdcxx-debug --disable-build-poststage1-
    with-cxx --enable-version-specific-runtime-libs --build=mingw32 --prefix=/mingw
    Thread model: win32
    gcc version 4.7.0 (GCC)

    Binutils Version:
    GNU ld (GNU Binutils) 2.22

     
  • Keith Marshall
    Keith Marshall
    2012-06-21

    • labels: 103944 --> non-mingw
    • milestone: --> Known_Feature
    • status: open --> closed-rejected
     
  • Keith Marshall
    Keith Marshall
    2012-06-21

    Herewith, my comments:

    1) The provider of your libc is Microsoft, (it's MSVCRT.DLL).

    2) Your test case is invalid; I had to modify it to even get it to compile!

    3) After removing all the invalid backslashes from your code, I can reproduce your result; however, I can equally easily correct the issue, getting correct results, by refactoring your code, to eliminate unsafe int --> double type coercions:

    $ cat foo.c
    #include <math.h>
    #include <stdio.h>

    int main( int argc, char **argv )
    {
    while( --argc )
    {
    int n = atoi( *++argv );
    int log = log10( n );
    do { int res = pow( 10, log );
    printf( "n = %d; log = %d; pow = %d\n", n, log, res );
    } while( log-- );
    }
    return 0;
    }

    $ gcc -o foo foo.c

    $ ./foo 1020 10230
    n = 1020; log = 3; pow = 1000
    n = 1020; log = 2; pow = 100
    n = 1020; log = 1; pow = 10
    n = 1020; log = 0; pow = 1
    n = 10230; log = 4; pow = 10000
    n = 10230; log = 3; pow = 1000
    n = 10230; log = 2; pow = 100
    n = 10230; log = 1; pow = 10
    n = 10230; log = 0; pow = 1

    4) There is a note about potential rounding (excess precision) errors in /mingw/include/math.h; you should read it.

    Given that this issue arises from improper use of Microsoft code, and is easily circumvented by writing your own code correctly, (i.e. avoiding unsafe implicit type coercions), we will not pursue this further.

     
  • Earnie Boyd
    Earnie Boyd
    2013-01-25

    • labels: non-mingw -->
    • status: closed-rejected --> closed
    • resolution: --> rejected
    • category: --> User_Error
    • milestone: Known_Feature --> WSL