1

I was doing some question in C and I was asked to provide the output of this question :

#include <stdio.h>

int main()
{
    float a =0.7;
    if(a<0.7)
    {
        printf("Yes");
    }
    else{
        printf("No");
    }
}

By just looking at the problem I thought the answer would be NO but after running I found that it was YES I searched the web about float and found 0.30000000000000004.com

Just out of curiosity I ran the same code in python :

x = float(0.7)
if x < 0.7 : 
    print("YES")
else : 
    print("NO")

Here the output is NO

I am confused!
Maybe I am missing something
Please help me with this problem.

Thanks in advance!

7
  • 1
    Looks like you have a double, convert it to float to than convert it back to double for the comparison. Loss of precision? Try 0.7f Commented Jun 16, 2020 at 7:37
  • 1
    Floating point math is not exact. In C, you're comparing a float version of 0.7 to a double version of 0.7. The double version is more accurate, and in this case the float version (which is converted to double for the comparison) happens to be smaller. In Python, float refers to a double-precision floating point number, so you're comparing a double 0.7 to another double 0.7, and the result is that they're equal. Commented Jun 16, 2020 at 7:40
  • Didn't you ask a question regarding this yesterday? And someone pointed out that a < 0.7 is a double but a is a float? Checked, nope, apparently you and another person had the same exact issue within 24h :) Commented Jun 16, 2020 at 7:41
  • ....almost like two assignment dumps. Commented Jun 16, 2020 at 10:30
  • 1
    @chux-ReinstateMonica This question was asked in the quiz. I ran it at that time and later searched for the reason. Commented Jun 16, 2020 at 17:21

2 Answers 2

1
float a = 0.7;
if(a<0.7)

The first line above takes the double 0.7 and crams it into a float, which almost certainly has less precision (so you may lose information).

The second line upgrades the float a to a double (because you're comparing it with a double 0.7, and that's one of the things C does for you) but it's too late at that point, the information is already gone.

You can see this effect with:

#include <stdio.h>

int main(void) {
    float a = 0.7;
    float b = 0.7f;
    double c = 0.7;
    printf("a %.50g\nb %.50g\nc %.50g\n", a, b, c);
    return 0;
}

which generates something like:

a 0.699999988079071044921875
b 0.699999988079071044921875
c 0.69999999999999995559107901499373838305473327636719

Clearly, the double c variable has about double the precision (which is why they're often referred to as single and double precision) than both:

  • the double 0.7 crammed into the float a variable; and
  • the float b variable that had the float 0.7 stored into it.

Neither of them is exactly 0.7 due to the way floating point numbers work, but the double is closer to the desired value, hence not equal to the float.

It's like pouring a full four-litre bucket of water into a three-litre bucket and then back again. The litre you lost in the overflow of the smaller bucket doesn't magically re-appear :-)

If you change the type of your a to double, or use float literals like 0.7f, you'll find things work more as you expect, since there's no loss of precision in that case.


The reason why you don't see the same effect in Python is because there's one underlying type for these floating point values:

>>> x = float(.7)
>>> type(x)
<class 'float'>
>>> type(.7)
<class 'float'>

From the Python docs:

There are three distinct numeric types: integers, floating point numbers, and complex numbers. In addition, Booleans are a subtype of integers. Integers have unlimited precision. Floating point numbers are usually implemented using double in C.

Hence no loss of precision in that case.

The use of double seems to be confirmed by (slightly reformatted):

>>> import sys
>>> print(sys.float_info)
sys.float_info(
    max=1.7976931348623157e+308,
    max_exp=1024,
    max_10_exp=308,
    min=2.2250738585072014e-308,
    min_exp=-1021,
    min_10_exp=-307,
    dig=15,
    mant_dig=53,
    epsilon=2.220446049250313e-16,
    radix=2,
    rounds=1
)

The exponents and min/max values are identical to those found in IEEE754 double precision values.

Sign up to request clarification or add additional context in comments.

Comments

0

In a<0.7 the constant 0.7 is a double then a which is a float is promoted to double before the comparison.
Nothing guarantees that these two constants (as float and as double) are the same.

As float the fractional part of 0.7 is 00111111001100110011001100110011; as double the fractional part of 0.7 is 0110011001100110011001100110011001100110011001100110.
The value converted from float will have its mantissa filled with 0s when promoted to double.
Comparing these two sequences of bits shows that the double constant is greater than the float constant (the second bit already differs), which leads to displaying "Yes".

On the other hand, in python, only the double representation exists for floating point numbers; thus there is no difference between what is stored in a and the constant 0.7 of the comparison, which leads to displaying "No".

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.