Click here to Skip to main content
15,899,126 members
Please Sign up or sign in to vote.
2.67/5 (3 votes)
See more:
What will be the output of the program?
C
#include<stdio.h>
int main()
{
 float a = 0.7;
 if(0.7 > a)
 printf("Hi\n");
 else
 printf("Hello\n");
 return 0;
}

the answer is given as hi...and i was expecting it to be hello.please help.
Posted
Updated 11-Feb-15 12:26pm
v2

Go through this article - Comparing floating point numbers[^].

"Floating point math is not exact. Simple values like 0.2 cannot be precisely represented using binary floating point numbers, and the limited precision of floating point numbers means that slight changes in the order of operations can change the result. Different compilers and CPU architectures store temporary results at different precisions, so results will differ depending on the details of your environment. If you do a calculation and then compare the results against some expected value it is highly unlikely that you will get exactly the result you intended."

Thus you can try if (fabs(0.7 - a) < 0.00001)
 
Share this answer
 
Comments
Andreas Gieriet 11-Feb-15 18:26pm    
My 5!
Cheers
Andi
Abhinav S 11-Feb-15 22:00pm    
Thanks.
Member 11324568 12-Feb-15 3:43am    
thanks yar ...abhinav :) my 5 *
There is a subtlety in you program: it

  1. Assigns a double constant (0.7 is a double literal) to a float variable (in this step rounding occurs).
  2. Compares such a float variable with (the same) double constant.


Try the following code:
C
#include<stdio.h>
int main()
{
  float a = 0.7f;
  if(0.7f > a)
    printf("Hi\n");
  else
    printf("Hello\n");
  return 0;
}


as well as

C
#include<stdio.h>
int main()
{
  double a = 0.7;
  if (0.7 > a)
    printf("Hi\n");
  else
    printf("Hello\n");
  return 0;
}



both of them output "Hello" on my system.
 
Share this answer
 
Comments
Andreas Gieriet 11-Feb-15 19:51pm    
On my system (VS2010) I get "Hi" only - i.e. not the "intuitive" solution...
Cheers
Andi
CPallini 12-Feb-15 2:57am    
Both of the above programs produce "Hello", compiled with Visual Studio 2013 Express.
Andreas Gieriet 12-Feb-15 4:35am    
Strange...
Any special rounding settings?
What is sizeof(double) and sizeof(float)? Mine is 8 and 4 respectively.
Cheers
Andi
CPallini 12-Feb-15 4:56am    
Here the same: compilers cannot cheat on that.
Andreas Gieriet 12-Feb-15 5:26am    
What do you get if you run my hack from solution 3?
Andi
You may try the following hack (on a little endian system):
C
// allow to extract the bit pattern of the floating point value (little endian)
typedef union {
  double d;
  struct { unsigned long long m:52, e:11, s:1; } x;
} double_union;
// allow to extract the bit pattern of the floating point value (little endian)
typedef union {
  float f;
  struct { unsigned long m:23, e:8, s:1; } x;
} float_union;
// aux function to write the floating values
void write_bits(long e, unsigned long long m, int is_float)
{
  size_t b = is_float ? 23 : 52;
  long bias = is_float ? 127 : 1023;
  size_t n = sizeof(m)*8;
  unsigned long long mask = (0x1ull << (n-1));
  printf("%s.", !e && !m ? "0" : "1");
  m <<= (n-b);
  while(b-- > 0)
  {
    printf("%s", (m & mask) ? "1" : "0");
    m <<= 1;
  }
  if (e) printf(" 2^%d", e-bias);
}
// write the float as bit-mantissa
void write_float(float_union u)
{
  printf("%s", u.x.s ? "-" : "+");
  unsigned long e = u.x.e;
  unsigned long m = u.x.m;
  write_bits(e, m, 1);
  printf("\n");
}
// write the double as bit-mantissa
void write_double(double_union u)
{
  printf("%s", u.x.s ? "-" : "+");
  unsigned long e = u.x.e;
  unsigned long long m = u.x.m;
  write_bits(e, m, 0);
  printf("\n");
}
// test program
int main()
{
  float a = 0.7;
  if(0.7 > a) printf("Hi\n");
  else        printf("Hello\n");

  double_union du;
  float_union  fu;

  fu.f = 0.7;
  write_float(fu);
  du.d = 0.7;
  write_double(du);
  du.d = fu.f;  // <----- THIS IS THE TROUBLESOME PART: float assigned to double
  write_double(du);

  return 0;
}
The output on my little endian system with 4-byte float and 8-byte double is
Hi
+1.01100110011001100110011 2^-1
+1.0110011001100110011001100110011001100110011001100110 2^-1
+1.0110011001100110011001100000000000000000000000000000 2^-1
This shows that the two values are not equal anymore.
0.7 is of type double.
0.7 > a promotes the float a value to a double value. This results in the above mentioned different values. The double 0.7 is indeed greater than the float 0.7f since the float value is promoted to the double value for comparison.

What to learn from this: never mix number domains, especially for floating point numbers.

See also What Every Computer Scientist Should Know About Floating-Point Arithmetic[^].


Cheers
Andi
 
Share this answer
 
v2
Comments
Member 11324568 12-Feb-15 3:41am    
that was awesome...thanks andi.. :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900