Menu

#650 printf doesn't like %lf?

v1.0 (example)
closed-invalid
nobody
None
5
2017-09-15
2017-08-16
No

try this with llf or lf, both give you 0.

#include <math.h>
#include <stdio.h>
int main() {
typedef long double LD;
LD intfractional=0x25+powl(2,-1)+powl(2,-3)+powl(2,-5);
LD ld=intfractional*powl(10,32);printf("%02.50llf\r\n",ld);
ld=intfractional*powl(10,-32);printf("%02.50llf\r\n",ld);
ld=intfractional*powl(10,+32);printf("%02.50llf\r\n",ld);
return 0;
}
/*
0.00000000000000000000000000000000000000000000000000
0.00000000000000000000000000000000000000000000000000
0.00000000000000000000000000000000000000000000000000
*/

Discussion

  • Doug Semler

    Doug Semler - 2017-08-16

    I have neither the specs nor my computer in front of me but offhand I am pretty sure the format specifier for long double is %Lf not %lf?

     
  • Jim Michaels

    Jim Michaels - 2017-08-16

    also, instead of 00. youget 0.
    you can mod the test with bit positions that are farther out there in the mantissa. there's probably >= 64 mantissa bits to tinker with.

    powl is working, but I get lots of FP error after about 17 digits precision.
    std::cout just renders 6 digits precision for long double, underwhelming and it's in the spec.

     
  • Jim Michaels

    Jim Michaels - 2017-08-16

    change lf to lg and you get a wrong result again:

    1.1330308642948138748e-317
    1.1330308642948138748e-317
    1.1330308642948138748e-317
    
     
  • Jim Michaels

    Jim Michaels - 2017-08-16

    to verify, use a sci calculator:
    0x25=37.
    37.65625 multiplied by 10^32 or 10^-32.

     
  • Doug Semler

    Doug Semler - 2017-08-16

    AGAIN, 'l' is not a valid modifier for long double parameter types. 'L' is the modifier you need to use on e/g/f format specifiers. PERIOD. FIX THAT FIRST. %lf tells the formatter that the argument is a double, not long double.

     
  • Doug Semler

    Doug Semler - 2017-08-16

    Also, your understanding of the 02 is incorrect. This is the minimum number of characters printed, not the number of leading zeros before the decimal point for padding.

     
  • Doug Semler

    Doug Semler - 2017-08-16

    By default the printf function is using the MS library which doesn't understand long double. If you want to use the mingw, add -D__USE_MINGW_ANSI_STDIO=1 to the command line which will use the mingw variant (as opposed to the default MSVC library). See also https://sourceforge.net/p/mingw-w64/bugs/520/

     
  • Doug Semler

    Doug Semler - 2017-08-16

    Finally, for the c++ version, look into the iomanip, specifically std::setprecision, std::setw, and std::setfill manipulators.

     
  • Doug Semler

    Doug Semler - 2017-08-16

    well I take that back on the default printf function...caveat being that using the C++ driver should get you the mingw ansi printf function by default. I did find a combination of headers that negates it for some reason, and that is if math.h is included AFTER stdio.h.

     
  • Jim Michaels

    Jim Michaels - 2017-08-22

    I already tried it with %lf and this is long double. in fact, I said that at the very first. must've got ignored.

     

    Last edit: Jim Michaels 2017-08-22
  • Doug Semler

    Doug Semler - 2017-08-22

    You do understand the difference between a lower case and upper case L, right? AFAIK, the standards specifies %Lf is the format specifier for long double, not %lf (which is double). %llf is not a valid format specifier for floating point. The default microsoft CRT as far as I know does not understand the long double format specifier nor does it properly understand passing from gcc code a long double as a vararg argument; I believe therefore in this situation you would be best served by using the correct format specifer %Lf and compiling with -D__USE_MINGW_ANSI_STDIO=1 which will then use the mingw-64 printf function that supports this.

     
  • niXman

    niXman - 2017-08-22
    • status: open --> closed-invalid
     
  • Jim Michaels

    Jim Michaels - 2017-09-15

    so, you mean to tell me that after all this printf in 6.1.0 should accept %Lf? OK. try this:
    I get zeros instead of x.

     
  • Jim Michaels

    Jim Michaels - 2017-09-15

    by the way, %Lf should be an automatic thing, not an exception. why isn't it in the spec by now with 80-bit floating point?

     
  • Jim Michaels

    Jim Michaels - 2017-09-15

    forgot to include the #define in that C code.

     

Log in to post a comment.

MongoDB Logo MongoDB