tags:

views:

283

answers:

5

In the code below, printf prints -0.00000. What is the problem? If it is double instead of long double, then it works fine.

#include<stdio.h>
long double abs1(long double x) {
    if (x<0.0)
        return -1.0*x;
    else
        return x;
}

main() {
    long double z=abs1(4.1);
    printf("%llf\n",z);
}
+7  A: 

The correct print format for a long double is %Lf. Turning on your compiler's warnings would have pointed out the mistake immediately:

$ gcc -Wall b.c -o b
b.c:9: warning: return type defaults to `int'
b.c: In function `main':
b.c:11: warning: use of `ll' length modifier with `f' type character
b.c:11: warning: use of `ll' length modifier with `f' type character
b.c:12: warning: control reaches end of non-void function
Mark Rushakoff
+2  A: 
$ gcc -Wall test.c
test.c:9: warning: return type defaults to 'int'
test.c: In function 'main':
test.c:11: warning: use of 'll' length modifier with 'f' type character
test.c:11: warning: use of 'll' length modifier with 'f' type character
test.c:12: warning: control reaches end of non-void function

Use %Lf instead of %llf

nos
+2  A: 

You need to use a capital L before the f in the printf statement, like so:

printf("%Lf\n", z);

I don't know why it's lowercase for long integer types and uppercase for floating-point.

elcelista
+4  A: 

The C formatter for long double is %Lf. Also, is there a reason not to use the math.h fabsl( ) function instead of rolling your own absolute value? (note that your absolute value function leaves the sign of minus zero unchanged, though that may not matter for your purposes; the standard fabsl function will generally be faster as well)

Stephen Canon
A: 

What compiler and target platform are you using?

Microsoft's library for example does not support long double (but does allow the format specifier), if you are using Microsoft's compiler that does not matter much because long double is a synonym for double, so it gets you nothing.

If however you are using MinGW/GCC, you are still using Microsoft's C library, but have an 80-bit long double. In MinGW the simplest solution is to use C++'s std::ostream since that uses the GNU library and does support long double.

Alternatively you could simply cast it to double to output it.

Clifford

Clifford