0

While studying the C essentials from online video, the author shared the code below to find the difference between float, double and long double. I ran this program in Eclispse running in 64 bit Windows 10 Laptop.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
puts("Floating point type usage in C:");

// Floating point types
float           floatNumber;
double          doubleNumber;
long double     longDoubleNumber;

// Size of floating point types
//lu - Stands for "unsigned decimal integer" and "long"
printf("Storage size for unsigned float : %lu  bytes \n", sizeof(float));
printf("Storage size for double :         %lu  bytes \n", sizeof(double));
printf("Storage size for long double :   %lu  bytes \n", sizeof(long double));

floatNumber = 2.0/3.0;
doubleNumber = 2.0/3.0;
longDoubleNumber = 2.0/3.0;

puts("\nCompare precision at 4 decimal points:");
printf("floatNumber      = %1.4f\n", floatNumber);
printf("doubleNumber     = %1.4lf\n", doubleNumber);
printf("longDoubleNumber = %1.4Lf\n", longDoubleNumber);

puts("\nCompare precision at 10 decimal points:");
printf("floatNumber      = %1.10f\n", floatNumber);
printf("doubleNumber     = %1.10lf\n", doubleNumber);
printf("longDoubleNumber = %1.10Lf\n", longDoubleNumber);

puts("\nCompare precision at 30 decimal points:");
printf("floatNumber      = %1.30f\n", floatNumber);
printf("doubleNumber     = %1.30lf\n", doubleNumber);
printf("longDoubleNumber = %1.30g\n", longDoubleNumber);
return 0;
}

Somehow,I am not getting the expected output. I have added the output that i had got in my Eclispse console. Could anyone help me to figure out what went wrong

Floating point type usage in C:
Storage size for unsigned float : 4  bytes 
Storage size for double :         8  bytes 
Storage size for long double :   16  bytes 

Compare precision at 4 decimal points:
floatNumber      = 0.6667
doubleNumber     = 0.6667
longDoubleNumber = 0.0000              //Expected value = 0.6667

Compare precision at 10 decimal points:
floatNumber      = 0.6666666865
doubleNumber     = 0.6666666667
longDoubleNumber = 0.0000000000   //Expected value = 0.6666666667

Compare precision at 30 decimal points:
floatNumber      = 0.666666686534881590000000000000 
doubleNumber     = 0.666666666666666630000000000000
longDoubleNumber = 3.1728895775924853e-317   //This is not the expected value
alk
  • 69,737
  • 10
  • 105
  • 255
prasanth_ntu
  • 19
  • 1
  • 7
  • 3
    What compiler & runtime/libc are you using? – R.. GitHub STOP HELPING ICE May 11 '16 at 03:33
  • Try `longDoubleNumber = (long double)2.0/3.0;` – sjsam May 11 '16 at 03:47
  • @sjsam, the lack of a cast in the original code may be intentional. In any event, it does not explain the output presented. – John Bollinger May 11 '16 at 03:50
  • 2
    The 30-digit variation should use `%1.30Lg` or `%1.30Lf`, not `%1.30f`. But I doubt that fix will get you the output you expect, since the other `long double` outputs are also incorrect. It looks to me as if your compiler or C library is buggy / non-conforming. – John Bollinger May 11 '16 at 03:53
  • 1
    @JohnBollinger: Or it could be a compiler / library mismatch. Eg. on Windows, msvcrt assumes that long double == double. – rici May 11 '16 at 05:48
  • [`sizeof` return a size_t which must be printed using `%zu`](https://stackoverflow.com/q/940087/995714) – phuclv Sep 09 '18 at 04:49

1 Answers1

0

I suggest you make a couple of corrections and then re-run your tests. First, we need to assure that all types are correct and no promotions, or other things are involved. We need to change

floatNumber = 2.0/3.0;
longDoubleNumber = 2.0/3.0;

to

floatNumber = 2.0f / 3.0f;
longDoubleNumber = 2.0L / 3.0L;

This is required to disallow promotions of the result to double (in the first case and type conversion from double to long double in second), because orginally both your operands were of type "double" in each case.

Secondly, you should get rid of undefined behaviour in

printf("longDoubleNumber = %1.30g\n", longDoubleNumber);

and use a proper long double length specifier in format string. It will look like this:

printf("longDoubleNumber = %1.30Lg\n", longDoubleNumber);

Notify us of the results.

HighPredator
  • 790
  • 4
  • 21
  • 1
    Although these changes are *reasonable*, it's not clear that all of them are appropriate for the the specific demonstrative purposes of the program. More importantly, however, it is unclear why you think these would resolve the specific output problems noted by the OP. Even the last suggested change -- which is, indeed, necessary -- seems unlikely to cause correct output to be produced given the nature of the earlier incorrect outputs. – John Bollinger May 11 '16 at 16:48
  • @JohnBollinger, I didn't say that they will, I said that they "should". I can agree however, that word "might" is more appropriate. The purpose of the changes is to negate possible side effects from type conversions. Once one can say that there are none, and if the problem persists in the same way, then we can go forward. That's the most reasonable approach that I see atm. – HighPredator May 12 '16 at 07:16
  • Even "might" is unreasonably optimistic. There is **no** reason to expect that the suggested changes would solve the OP's main problems. – John Bollinger May 12 '16 at 14:02
  • @JohnBollinger, fine, have it your way. – HighPredator May 12 '16 at 14:13