1.
#include<stdio.h>
#include<conio.h>
int main()

    int a=10;
    printf("%d%d%d",a,a++,++a);
    getch();
        return 0;
}
o/p:12 11 11
#include<stdio.h>
#include<conio.h>
int main()
{
    double a=5.2;
    if(a==5.2)
    printf("equal");
    else if(a<5.2)
    printf("less");
    else
    printf("high");
    getch();
}
o/p: less

Can any one give me explanation for the above outputs.....

Recommended Answers

All 23 Replies

The first is undefined behavior because there is no sequence point between function arguments.

The second might be due to differences in precision when the value is only held in a register versus when it is stored in memory. That's my best guess anyway (though I don't think it's conforming behavior).

if(a==5.2)

Should never test for equality with floats and doubles because of extraneous fractional values beyond your control, which is due to the way floats/doubles are stored in memory. The value 5.2 might actually be stored in memory as 5.200001 and the test for equality will fail. Since the program printed "less" my guess is that the value of variable named a might be something like 5.199999

The value 5.2 might actually be stored in memory as 5.200001

You make it sound like it's non-determinstic. If 5.2 and 5.200001 are the same number under the given floating point representation, x == 5.2 and x == 5.200001 should simply both return true if x has been set to 5.2. Generally in a conforming implementation foo = constant; foo == the_same_constant; should only ever produce false if foo and the constant have different types (and thus the assignment causes a conversion) - unless I'm missing something. Floating point inaccuracies should only bite you if you're doing arithmetic.

If 5.2 and 5.200001 are the same number under the given floating point representation,

They are not the same, which is why you can't test for equality. If you want to learn more about it read this wiki article

I understand floating point. I'm saying if 5.2 is represented as 1.m * 2**e, which happens to be 5.2000001, then 5.2 == 5.2000001 should still be true because it'd just be 1.m * 2**e == 1.m * 2**e.

Not quite right though, sepp2k.

5.2 is an absolute value - it is NOT the same as the double a which was assigned the value of 5.2 AS A DOUBLE.

5.2000000 != 5.2000001 in your example.

Try this:

double a,b;
a=5.2;
b=5.2;

if(a==b) 
   printf("equal\n");
else if(a<b)
   printf("a is less than b\n");
else 
   printf("b is less than a\n");

5.2 is an absolute value - it is NOT the same as the double a which was assigned the value of 5.2 AS A DOUBLE.

Isn't 5.2 simply a constant of type double?

The 'a' variable is, but the other 5.2 was never assigned into a variable. It has no data type yet.

My understanding is the following: expressions have types. A variable is one kind of expressions - constants are another. Integral constants default to type int and floating point constants default to type double. A constant can be given a different type using a suffix (like l to make an integral constant type long or f to make a floating point constant type float). Is this not correct?

Is this not correct?

Perfectly correct.

Generally in a conforming implementation foo = constant; foo == the_same_constant; should only ever produce false if foo and the constant have different types (and thus the assignment causes a conversion) - unless I'm missing something. Floating point inaccuracies should only bite you if you're doing arithmetic.

This is also the correct answer. As for why the OP's program failed to produce the correct behavior, we'd need to know details about the platform and compiler to diagnose non-conformancy. I'm willing to bet we're looking at a Turbo Crap quirk.

Boost apparently thought it is important enought to write a library for floating point comparisons.

In most cases it is unreasonable to use an operator==(...) for a floating-point values equality check.

In most cases it is unreasonable to use an operator==(...) for a floating-point values equality check.

Nobody argued against that. I get that and why 0.1 + 0.2 will not equal 0.3 and that it is dangerous to use == to compare floating point values because it can give results like this when doing arithmetic (or conversions between floating point types of different width).

I just said that in this specific case, where there was no arithmetic and no conversions, I see no reason why a conformant implementation would return false for ==.

But 5.2 is not a constant yet - nor a float, nor a double, nor any other data type.

5.2 is just 5.2, until it is assigned to a variable. Nothing else.

Of course it's a constant (or literal if you prefer that term - though the standard uses the term constant). I may not be an absolute expert on every quirk of the C standard, but I know that much for sure.

If 5.2 is not a double, does that mean that 5.2f is not a float? If so what is the difference between 5.2 and 5.2f?

I tested the original problem in this thread on VC++ 2012 and it produced the expected results -- "equal". But other compilers may produce different results, especially old MS-DOS programs such as Turbo C and Microsoft C (the version released prior to year 2000).

5.2 is just that: 5.2. Until it is assigned to the data type, it won't be coerced into a double, a float, or anything else.

Okay, that's just not true. Here's the relevant excerpts from the 99 standard (section 6.4.4.2 "Floating Constants"):

Description:

A floating constant has a significand part that may be followed by an exponent part and a suffix that specifies its type. The components of the significand part may include a digit sequence representing the whole-number part, followed by a period (.), followed by a digit sequence representing the fraction part. The components of the exponent part are an e, E, p, or P followed by an exponent consisting of an optionally signed digit sequence. Either the whole-number part or the fraction part has to be present; for decimal floating constants, either the period or the exponent part has to be present.

Semantics:

[...] For decimal floating constants [...] the result is either the nearest representable value, or the larger or smaller representable value immediately adjacent to the nearest representable value, chosen in an implementation-defined manner.[...]

An unsuffixed floating constant has type double. If suffixed by the letter f or F, it has type float. If suffixed by the letter l or L, it has type long double.

As you see in the description a floating constant would be something like 5.2 (whereas a would be a variable - not a constant). And as the bolded part in the semantics indicates, the type of a floating literal without a suffix is indeed double.

Are you saying then, that a "magic number", like 5.2, dropped in as it were from the Underverse (wherever), is made into a floating constant?

Not the variable a, but the value 5.2 itself.

A value like 5.2 is not a floating constant, UNTIL IT'S ASSIGNED to be such. You can't DO ANYTHING with 5.2 until that time, except make comparisons.

But I don't recall what the standard says about "magic numbers", and how they're handled. Any info on that in there?

What you call magic numbers, is called a constant. And the section I quoted tells you exactly how constants are handled.

Note that the standard specifically says that a sequence of digits containing a . or an e, E, p or P is a floating constant. It does not say anything about the sequence having to appear in a specific context to be a constant. If it's a sequence of digits with a . in between, it's a floating constant. And if it does not have a suffix, its type is double.

The three paragraphs you quote above ALL refer to floating constants, and clearly state that, right at the start of each paragraph.

"Magic numbers" are not mentioned. If it did, I would not hesitate to say you are correct. What you quoted is not what you are asserting, above. Those remarks refer to a sequence of digits IN constants. It says nothing about a sequence of digits which are NOT constants.

You see the part about the "nearest representable value..." being given to the constant.

My contention is that a magic number is simply a series of bytes, and have not yet been rounded by any floating point conversion to the nearest representable value.

Thus the results you see mentioned by the OP of this thread, where "a=5.2", but then a != 5.2.

If the magic number 5.2 WAS already a constant, it would already be perfectly equal to "a".

I used this simple bit of code.

#include <stdio.h>

int main(void) {
   int a=5.2;
   if(a==5.2)
      printf("Equal\n");
   else
      printf("Not Equal\n");

   return 0;
}

Result: Not Equal

The facts in this case, do not agree with your assertion. Perhaps with other compilers, it would. Try it with yours and report what you get.

If the facts agreed with you, I would as well. They don't, however.

the program you posted is incorrect. line 4 should be double, not int.

I tested it with both Code::Blocks which uses gcc compiler and VC++ 2012 and they both report "equal"

Thanks, AD. Best reason in the world not to code while distracted.

Pelles C also returns "Equal", so sepp2k, you are proven correct!, with the more modern compilers innumerated here.

Which strongly suggests that handling "magic numbers" as constants is in line with common compilers, and probably, in line with the standard, as well.

So congrats sepp2k!

I think there's been an important confusion of terminology here, so I just want to clear this up:

The three paragraphs you quote above ALL refer to floating constants, and clearly state that, right at the start of each paragraph.

Yes, because, as I said, what you call "magic numbers" is called a constant. The standard defines a floating constant as a sequence of digits with a dot in between (or an E or whatever). Unless I completely missed your point, that's what you refer to when you use the term "magic number": a sequence of digits. The term "magic number" does not exist in the standard.

handling "magic numbers" as constants

They aren't "handled" as constants, they are what standard defines to be a constant. The terms (integer + floating) "constant", as defined by the standard, and "magic number", as used by you, are 100% equivalent (again: unless I completely misinterpreted what you're trying to say). There's nothing that you would call a magic number that doesn't meet the standard's definition of a constant and there's nothing that would meet the standard's definition of a floating or integer constant that you would not call a constant.

commented: Beat me to it. :) +12
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.