Menu

pow error

 
2008-11-22
2012-09-26
  •  

      - 2008-11-22

    When I make this function call: x = pow(12.0, 28.0);

    x = 1648446623609512500000000000000 instead of 1648446623609512543951043690496.

    You'll note that the first 17 digits are correct and the length is the same. I double checked the float limits for my box and I should be able to display 53 numbers before the decimal for a double.

    I'm using Bloodshed 4.9.9.2 on an AMD Phenom 9850.

    Am I doing something wrong here or can I safely blame the compiler or chipset? Or what?

    Many thanks in advance,
    Chris

     
    • cpns

      cpns - 2008-11-24

      > In the meantime, here is the compiler log from both Bloodshed and gcc.

      Bloodshed Dev-C++ is not a compiler it is an IDE. It uses MinGW/GCC. i.e. it is gcc. I guess you meant Dev-C++ and gcc on some other platform?

      You appear to have enabled profiling: ( -lgmon -pg ). Did you intend to do that. In fact you have specified -pg twice. I suggest that you start with a default configuration and don't modify any defaults. I can think of no advantage in profiling this code.

      The log says: "Compilation successful", so I am not sure what your problem is.

      > I actually meant to include the Bloodshed compile log
      > with -Wall but it appears it does nothing

      What makes you think that? I can assure you that it does. But maybe there is nothing in this code to warn about. The verbose mode output is probably unnecessary, but I can see nothing wrong.

      Currently you have said that it does not compile, but you have posted a log that indicates successful compilation. What is actually wrong?

      I would suggest that you use Dev-C++'s project tool rather than direct compilation. That will split compilation from linking, which may help in diagnosis. Also you have not mentioned what OS you are using. There are know issues with Vista for example (and known solutions).

      Clifford

       
    • cpns

      cpns - 2008-11-22

      > I double checked the float limits for my box and I should be able
      > to display 53 numbers before the decimal for a double.

      I wonder how you figured that out. It is not true, and easy to see why it is impossible. A double has 64bits, that's 2^64 combinations. 2^64 as a decimal is only a 20 digit number, so how could you possibly have 53 digits of precision!?

      > Am I doing something wrong here or can I safely blame the compiler or chipset?
      Neither.

      Due to the nature of the binary floating point representation (IEEE-754), double precision (64bit) floating point precision is limited to approximately 16 decimal digits of significant figures. So the answer is an approximation.

      There are an infinite number of real numbers, but a finite number of values that can be represented by a 64bit binary value. Something has to give! Double precision FP values are restricted in both range and precision.

      See the following to understand why this is so:
      http://docs.sun.com/source/806-3568/ncg_goldberg.html
      http://en.wikipedia.org/wiki/Double_precision
      http://en.wikipedia.org/wiki/IEEE_754
      http://en.wikipedia.org/wiki/Floating_point

       
    •  

        - 2008-11-23

      I came up with the number 53 using this code (provided by my college instructor as floatlimits.c):

      include <stdio.h>

      include <stdlib.h>

      include <float.h>

      int main()
      {
      printf(" \n\ Some Floating Point Parameters From float.h\n\ +==================================================================================+\n\ | Parameter | Float | Double | Long Double |\n\ +-----------------------+------------------+-------------------+-------------------+\n\ | Minimum Exponent | %14d | %14d | %14d |\n\ +-----------------------+------------------+-------------------+-------------------+\n\ | Maximum Exponent | %14d | %14d | %14d |\n\ +-----------------------+------------------+-------------------+-------------------+\n\ | Digits in the Number | %14d | %14d | %14d |\n\ +-----------------------+------------------+-------------------+-------------------+\n\ ", FLT_MIN_10_EXP,DBL_MIN_10_EXP, LDBL_MIN_10_EXP \ , FLT_MAX_10_EXP, DBL_MAX_10_EXP, LDBL_MAX_10_EXP \ , FLT_MANT_DIG, DBL_MANT_DIG, LDBL_MANT_DIG \ );
      exit(0);
      }

      Another question I have, is if a 64 bit double can only display a 20 digit number accurately, then why do I get 17 digits followed by 0's instead of 20? And finally why does it compile fine under GCC for FreeBSD and Visual C++ but not Bloodshed?

       
    • cpns

      cpns - 2008-11-23

      DBL_MANT_DIG is the number of binary digits in the mantissa not decimal digits!

      I am sure that the links I posted would have made that obvious, but I also looked in the <float.h> (for VC++ - I no longer have Dev-C++ installed), and it says:

      define DBL_MANT_DIG 53 / # of bits in mantissa /

      The code you posted is all very well, but it would have been far easier to just open <float.h> and take a look!

      > [...] if a 64 bit double can only display a 20 digit number
      > accurately, if a 64 bit double can only display a 20 digit
      > number accurately?

      Ouch! that is not what I said. I said that there were 2^64 possible combinations which is a 20digit integer - that is the number of bit combinations, not the number of digits that can be represented. The point being that the number of significant digits must be somewhat less than this. So it would be impossible to have 53 significant digits in a double - it was the process of a thought experiment. From that you don't need to know the details of the representation to know that your assertion was at least impossible.

      The actual details are better described in the links I posted that I could do here. Read them rather than get confused by my ramblings. In fact given the nature of your tutor's code I can only imagine that he would have expected you to have read and understood something very similar.

      > And finally why does it compile fine under GCC for FreeBSD
      > and Visual C++ but not Bloodshed?
      I have no idea. No doubt the Compile Log migh shine some light, but you have not posted it. I don't have Dev-C++ installed so if you want an answer, post the log.

      Note that the line continuation characters here:

      ", FLT_MIN_10_EXP,DBL_MIN_10_EXP, LDBL_MIN_10_EXP \
      , FLT_MAX_10_EXP, DBL_MAX_10_EXP, LDBL_MAX_10_EXP \
      , FLT_MANT_DIG, DBL_MANT_DIG, LDBL_MANT_DIG \

      are completely unnecessary. Line continuation is clumsy at best, teh code would be better written thus:

      include <stdio.h>

      include <stdlib.h>

      include <float.h>

      int main()
      {
      printf(" \n"
      "Some Floating Point Parameters From float.h\n"
      "+==================================================================================+\n"
      "| Parameter | Float | Double | Long Double |\n"
      "+-----------------------+------------------+-------------------+-------------------+\n"
      "| Minimum Exponent | %14d | %14d | %14d |\n"
      "+-----------------------+------------------+-------------------+-------------------+\n"
      "| Maximum Exponent | %14d | %14d | %14d |\n"
      "+-----------------------+------------------+-------------------+-------------------+\n"
      "| Digits in the Number | %14d | %14d | %14d |\n"
      "+-----------------------+------------------+-------------------+-------------------+\n",
      FLT_MIN_10_EXP,DBL_MIN_10_EXP, LDBL_MIN_10_EXP,
      FLT_MAX_10_EXP, DBL_MAX_10_EXP, LDBL_MAX_10_EXP,
      FLT_MANT_DIG, DBL_MANT_DIG, LDBL_MANT_DIG
      );

      return 0 ;
      }

      Note that there are no commas between the literal string constants. In C adjacent string literals are concatenated, so you do not need a sungle string and line continuation.

      Using exit(0) rather than return is just 'unusual', as is placing comma delimiters at the start of teh next line rather than the end of the previous.
      Clifford

       
    • &amp;nbsp;

      &amp;nbsp; - 2008-11-24

      Thank you again for your response and the additional information. I will surely need to do more reading on the subject.

      In the meantime, here is the compiler log from both Bloodshed and gcc.

      The sample code is:

      include <stdio.h>

      include <stdlib.h>

      include <math.h>

      int main(void) {
      printf("%.0f\n", pow(12.0, 28.0));
      return 0;
      }

      The compile log from Bloodshed is:
      Compiler: Default compiler
      Executing d:\dev-cpp\bin\gcc.exe...
      d:\dev-cpp\bin\gcc.exe "D:\PCC\CS133U\Lab7\test.c" -o "D:\PCC\CS133U\Lab7\test.exe" -pg -g3 -I"D:\Dev-Cpp\include" -L"D:\Dev-Cpp\lib" -lgmon -pg -g3
      Execution terminated
      Compilation successful

      Here is the compile log from gcc:
      $ gcc -v -Wall -o test test.c
      Using built-in-specs.
      Target: i386-undermydesk-freebsd
      Configured with: FreeBSD/i386 system compiler
      Thread model: posix
      gcc version 4.2.1 20070719 [FreeBSD]
      /usr/libexec/cc1 -quiet -v -D_LONGLONG test.c -quiet -dumpbase test.c -auxbase test -Wall -version -o /var/tmp//ccIZK0eZ.s
      ignoring duplicate directory "/usr/include"

      include "..." search starts here:

      include <...> search starts here:

      /usr/include
      End of search list.
      GNU C version 4.2.1 20070719 [FreeBSD] (i386-undermydesk-freebsd)
      compiled by GNU C version 4.2.1 20070719 [FreeBSD].
      GGC heuristics: --param ggc-min-expand=99 --param ggc-min-heapsize=129459
      Compiler executable checksum: 51cd82042bcd96cdd6f36e6a6e1399b5
      /usr/bin/as -o /var/tmp//ccI4HAb2.o /var/tmp//ccIZK0eZ.s
      /usr/bin/ld --eh-frame-hdr -V -dynamic-linker /libexec/ld-elf.so.1 -o test /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib -L/usr/lib /var/tmp//ccI4HAb2.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/crtend.o /usr/lib/crtn.o
      GNU ld version 2.15 [FreeBSD] 2004-05-23
      Supported emulations:
      elf_i386_fbsd
      $

      So I noticed this line: /usr/libexec/cc1 -quiet -v -D_LONGLONG test.c....
      Is gcc simply realizing that I'm noob and correcting the problem?

       
    • &amp;nbsp;

      &amp;nbsp; - 2008-11-24

      I actually meant to include the Bloodshed compile log with -Wall but it appears it does nothing so I also tried -v but it won't properly compile... it did however give me more output. Although it might be meaningless, I've posted it anyways:

      Compiler: Default compiler
      Executing d:\dev-cpp\bin\gcc.exe...
      d:\dev-cpp\bin\gcc.exe "D:\PCC\CS133U\Lab7\test.c" -o "D:\PCC\CS133U\Lab7\test.exe" -v -pg -g3 -I"D:\Dev-Cpp\include" -L"D:\Dev-Cpp\lib" -lgmon -pg -g3
      Reading specs from d:/dev-cpp/bin/../lib/gcc/mingw32/3.4.2/specs
      Configured with: ../gcc/configure --with-gcc --with-gnu-ld --with-gnu-as --host=mingw32 --target=mingw32 --prefix=/mingw --enable-threads --disable-nls --enable-languages=c,c++,f77,ada,objc,java --disable-win32-registry --disable-shared --enable-sjlj-exceptions --enable-libgcj --disable-java-awt --without-x --enable-java-gc=boehm --disable-libgcj-debug --enable-interpreter --enable-hash-synchronization --enable-libstdcxx-debug
      Thread model: win32
      gcc version 3.4.2 (mingw-special)
      d:/dev-cpp/bin/../libexec/gcc/mingw32/3.4.2/cc1.exe -quiet -v -ID:\Dev-Cpp\include -iprefix d:\dev-cpp\bin../lib/gcc/mingw32/3.4.2/ -dD D:\PCC\CS133U\Lab7\test.c -quiet -dumpbase test.c -auxbase test -g3 -g3 -version -p -o C:\Users\Chris\AppData\Local\Temp/ccQrbaaa.s

      ignoring nonexistent directory "d:/dev-cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../mingw32/include"
      ignoring nonexistent directory "/mingw/include"
      ignoring nonexistent directory "/mingw/include"
      ignoring nonexistent directory "/mingw/lib/gcc/mingw32/3.4.2/include"
      ignoring nonexistent directory "/mingw/mingw32/include"
      ignoring nonexistent directory "/mingw/include"

      include "..." search starts here:

      include <...> search starts here:

      D:/Dev-Cpp/include
      d:/dev-cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../include
      d:/dev-cpp/bin/../lib/gcc/mingw32/3.4.2/include
      End of search list.
      GNU C version 3.4.2 (mingw-special) (mingw32)
      compiled by GNU C version 3.4.2 (mingw-special).
      GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072

      d:/dev-cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../mingw32/bin/as.exe -o C:\Users\Chris\AppData\Local\Temp/ccwJcaaa.o C:\Users\Chris\AppData\Local\Temp/ccQrbaaa.s

      d:/dev-cpp/bin/../libexec/gcc/mingw32/3.4.2/collect2.exe -Bdynamic -o D:\PCC\CS133U\Lab7\test.exe d:/dev-cpp/bin/../lib/gcc/mingw32/3.4.2/../../../crt2.o d:/dev-cpp/bin/../lib/gcc/mingw32/3.4.2/../../../gcrt2.o d:/dev-cpp/bin/../lib/gcc/mingw32/3.4.2/crtbegin.o -LD:\Dev-Cpp\lib -Ld:/dev-cpp/bin/../lib/gcc/mingw32/3.4.2 -Ld:/dev-cpp/bin/../lib/gcc -Ld:/dev-cpp/bin/../lib/gcc/mingw32/3.4.2/../../../../mingw32/lib -Ld:/dev-cpp/bin/../lib/gcc/mingw32/3.4.2/../../.. C:\Users\Chris\AppData\Local\Temp/ccwJcaaa.o -lgmon -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -lgmon -luser32 -lkernel32 -ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt d:/dev-cpp/bin/../lib/gcc/mingw32/3.4.2/crtend.o

      Execution terminated

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.