0

Consider the following code:

#include<stdio.h>
#define k 0.7
#define p 0.5
int main()
{
    float a=k,b=p;
    double aa=k;
    if(a<k)
    {
         if(b<p) printf("2 is right");    
         else      printf("1 is right");
    }
    else printf("0 is right");
    printf("\n");
    if(a>k)
    {
         if(b<p) printf("2 is right");    
         else      printf("1 is right");
    }
    else printf("0 is right");
    return 0;
}

Consider this as part II of this question, here the understanding was that the double precision values of floating point constants (doubles when represented as numeric constants) was lost when it was converted to their corresponding floating point values. The exceptional values were X.5 and X.0. But I observed the following results:

Input           Output
K=0.1 to 0.4        0 is right
                    1 is right

K=0.5               0 is right
                    1 is right

K=0.6               0 is right
                    1 is right

K=0.7               1 is right
                    0 is right

K=0.8               0 is right
                    1 is right

K=0.9               1 is right
                    0 is right

K=8.4               1 is right
                    0 is right

Why is this queer behavior? How come only few floating point values are displaying this property? Can't we assume that float precision values are always less than double precision values?? How do we explain this behavior?

Community
  • 1
  • 1
sasidhar
  • 7,523
  • 15
  • 49
  • 75
  • `a` is always equal to `k` in your example. Where is the input coming into play? –  Jul 18 '12 at 12:21
  • Sometimes casting a `double` to `float` yields a smaller value, sometimes a larger one, occasionally the value is the same. What's the problem? – Daniel Fischer Jul 18 '12 at 12:22
  • @0A0D really?? then in all cases i should have `0 is right` as answer. See properly before you downvote – sasidhar Jul 18 '12 at 12:25
  • @sasidhar: `float a = k;`... where is `a` changed before `if (a –  Jul 18 '12 at 12:26
  • @DanielFischer that is too ambiguous, right? Isn't there a way to predict the output? When someone asks me such a question should i answer `it depends!!`?? – sasidhar Jul 18 '12 at 12:27
  • @0A0D `a` is not changed before `if(a – sasidhar Jul 18 '12 at 12:28
  • @sasidhar: You say "Input 0.1 to 0.4" - where are you exercising that? This question is not clear and is too ambiguous. No one is jumping on answering it because we are having trouble trying to figure out what exactly is your question. –  Jul 18 '12 at 12:29
  • 1
    @sasidhar It depends on the binary expansion of the number. Casting from `double` to `float` reduces the precision from 53 to 24 bits. If the 25-th bit is 0, it truncates (rounds towards zero), if it's 1, it rounds away from zero, unless the 25-th bit is the last 1-bit, then it rounds so that the 24-th bit is 0. – Daniel Fischer Jul 18 '12 at 12:31

1 Answers1

2

Can't we assume that float precision values are always less than double precision values??

Not really, they may both have the same precision. You can assume that the range and precision of double is not smaller than that of float.

But, for all practical purposes, it's a profitable bet that double has 53 bits of precision and float has 24. And that double has 11-bit exponents, float 8-bit.

So, disregarding exotic architectures, float has less precision and a smaller range than double, every float value is representable as a double, but not vice versa. So casting from float to double is value-preserving, but casting from double to float will change all values needing more than 24 bits of precision.

The cast is generally performed (for values in the float range) by rounding the significand of the double value to 24 bits of precision in the following way:

  • if the 25th most significant bit of the significand is 0, the significand is truncated (the value is rounded towards zero)
  • if the 25th most significant bit is 1, and not all bits of lower significance are 0, the value is rounded away from zero (the significand is truncated and then the value of the lest significant bit is added)
  • otherwise, the significand is rounded so tat the 24th most significant bit is zero, that rounds away from zero in half the cases and towards zero in half.

You cannot predict if casting a double to float increases or decreases the value by looking at the decimal expansion, except in the few cases where you can see that the value will be unchanged. It's the binary expansion that matters.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431