8

I am trying to print floats. Although variadic functions does not work with floats so they are promoted to double. I can manage to get rid of the warning by casting it to a double. While printing the results on some powerpc architecture, it gives incorrect value if printed with %f. Why ?

Test Code:

 #include <stdio.h>

 #define _echo_size(X) \
        printf ("Sizeof "#X" %u\n", sizeof(X))

int main (void)
{

        float x;
        long usec = 7L;

        _echo_size(float);
        _echo_size(double);
        _echo_size(short);
        _echo_size(int);
        _echo_size(long);
        _echo_size(long long);

        x = ((float) usec) / 2;
        printf("Expected: 3.5 Got: %1.1f\n", (double) x);
        printf("Expected: 3.5 Got: %1d.%.1d\n", (int)x,
                (int)((x-(int)x)*10));
        return 0;
}

X86 system result:

Sizeof float 4
Sizeof double 8
Sizeof short 2
Sizeof int 4
Sizeof long 8
Sizeof long long 8
Expected: 3.5 Got: 3.5
Expected: 3.5 Got: 3.5

ppc system result:

Sizeof float 4
Sizeof double 8
Sizeof short 2
Sizeof int 4
Sizeof long 4
Sizeof long long 8
Expected: 3.5 Got: 0.0  <--- Why this ?
Expected: 3.5 Got: 3.5

Is it a bug in the tool-chain ? otherwise what is the elegant way to print floats ?

Constantinius
  • 34,183
  • 8
  • 77
  • 85
ededdy
  • 81
  • 3
  • @Felice No I did not. Just tried, its the same result. Although I don't understand how it could have any difference. – ededdy Jan 15 '13 at 14:12
  • 4
    @FelicePollano What would that solve? – Lundin Jan 15 '13 at 14:13
  • 1
    My guess is that you didn't link a floating point library to the project. Some embedded compilers give you the option to use standard libraries without support for float numbers, for performance reasons. But I still think you should have gotten some sort of error in that case. – Lundin Jan 15 '13 at 14:15
  • 1
    Did you try to compile with `-mfloat-abi=softfp`? – Benny Jan 15 '13 at 14:56
  • 2
    which OS ? which compiler ? what compiler flags ? – Sander De Dycker Jan 15 '13 at 14:59
  • @Lundin: I'm not aware of a PPC without an FPU; IIRC it's required. – tc. Jan 16 '13 at 03:08
  • @tc. FPU or not, some libraries (like stdio.h) can be implemented in far more efficient ways if they don't need to bother about all floating point cases. So it still makes sense that the compiler has an option to ignore them. For example I am currently working with a Power PC that has a FPU, but since I don't need floats, I have chosen a more efficient standard library through a compiler option. – Lundin Jan 16 '13 at 07:18
  • @tc Many embedded PowerPCs don't have FPUs. For example the MPC8xx series. – Kalle Pokki Jan 17 '13 at 14:11
  • Has this problem been solved? – phonetagger Jan 31 '13 at 21:29
  • Has this problem been solved? What processor are you using? I tried this on my PowerPC Linux + GCC server and it works fine. But mine isn't an embedded PPC lacking an FPU. – phonetagger Jan 31 '13 at 21:47
  • Trace your assembler and see what's going on. The only way to be sure... – Michael Dorgan Jan 31 '13 at 22:20

2 Answers2

1

Oh, DUH! Your floating point value for x is being computed correctly, regardless of whether your FPU is doing it or if your compiler is doing it for you in software; it's just that your printf() implementation apparently doesn't treat %f as a double...

Are you on an embedded system with a custom printf() implementation? If so, it likely wasn't written to handle floating point numbers anyway, since floating point numbers often aren't even used in embedded systems, where programmers often opt to use integer variables & fixed point arithmetic, which is historically much much faster than floating point (and may still be on small embedded systems).

Or, another possibility: Your custom printf() is written to handle floating point numbers, but treats %f as a float, even though your compiler promotes float to double when passing it through .... Find your custom implementation & fix it to pull %f off the stack as a double instead of a float. (Your custom implementation may be getting a warning by trying to do that anyway, which people may have just been ignoring.) Search for va_arg(args,float) in that code and change it to va_arg(args,double). (Of course args in that example is my own variable name for a va_list; your variable name might be different.)

phonetagger
  • 7,701
  • 3
  • 31
  • 55
-3

I guess it's all about "Big Endian" and "Little Endian"

Kowalski
  • 76
  • 4