0
#include<iostream.h>
using namespace std;
int main()
{
      float x=1.1;
      if(x==1.1)
         cout<<"yes";
      else
         cout<<"no";
      return 0;
}

I assign value 1.1 to x and checked value of x is 1.1 or not?

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
hrishi007
  • 113
  • 2
  • 7
  • 2
    `` -- What compiler are you using? The standard header is ``, not ``, and it has been standard for 20 years now. – PaulMcKenzie Dec 30 '18 at 04:10
  • The *"Is floating point math broken?"* link does not answer the question. There is no math involved here, only data types. So this should be reopened or closed as a duplicate of something else. – Sid S Dec 30 '18 at 04:28
  • 1
    @SidS - Hmmm, checking it carefully, I guess I agree. It also covers things at a level that I don't think the OP is prepared to deal with. – Omnifarious Dec 30 '18 at 04:31
  • No, @SidS - this is precisely because floating point math is broken. There is certainly math involved here: the conversion from float to double. However I do agree that this shouldn't be dupe-hammered, as the canonical does not fully explain this nuanced situation. This deserves an upvote, for highlighting this unexpected situation where floating point math is a factor, but not an obvious one. – Sam Varshavchik Dec 30 '18 at 05:01
  • @StoryTeller, This is not a case of *"strange output in comparison of float with float literal"*. The OP tries to compare a `float` with a `double` literal, – Sid S Dec 30 '18 at 08:31
  • @SidS - It is exactly the case. Did you even read beyond the dupe's title? The only difference is that the literal in question is 0.7 and not 1.1 – StoryTeller - Unslander Monica Dec 30 '18 at 08:32
  • @StoryTeller, No it isn't. `0.7` and `1.1` are both `double` literals. – Sid S Dec 30 '18 at 08:34
  • @SidS - Yes. As the answer to **the dupe** explains – StoryTeller - Unslander Monica Dec 30 '18 at 08:35
  • @StoryTeller, *"the answer"* also states that *"you should never test for exact equality of floating-point values"* and that is just plain wrong as far as the question at hand is concerned. – Sid S Dec 30 '18 at 08:40
  • 1
    I posted more information in the duplicate answer, this is 100% a duplicate question. The fraction matters, combine Omnifarious and SidS's answers in this question. You should never ever do an equals comparison in float certainly for formats that can have the same value with two different bit patterns as the equals is a bit pattern comparison. In this case the values 1.1 or 0.7 cannot be completely and accurately represented in IEEE 754 single precision floating point format so jumping between double to single to double as in the question results in a bit pattern that doesnt match. – old_timer Dec 30 '18 at 08:55
  • 1
    Now if there is an issue with the language of the questions float literal or whatever, then just edit the question...There is no way that these two can be considered different questions. the equals failed because is the question and the reason is the same... – old_timer Dec 30 '18 at 08:58
  • 1
    @old_timer: Testing for floating-point comparison is not bit-pattern comparison. The different bit patterns for −0 and +0 compare as equal, while the same bit pattern for two instances of a NaN compares as not equal. – Eric Postpischil Dec 30 '18 at 09:51
  • @old_timer: `1.1` and `1.1f` do not produce “the same value with two different bit patterns.” They produce different bit patterns. In each case, the decimal numeral in the source text is **converted** to the nearest representable value in the designated type. The result represents that nearest representable value. It does not represent 1.1. – Eric Postpischil Dec 30 '18 at 09:56
  • @EricPostpischil depends on the revision of the spec and the implementation of the hardware. The root of the dont use equals comes from different ways to represent the same number. – old_timer Dec 30 '18 at 16:51
  • @EricPostpischil 1.1 and 1.1f when converted to single do produce the same bit pattern as well as value in the case where it works 1.1 is converted to single, then 1.1f is already single and directs the compiler to do a single comparison not a double comparison. the equals then works both bitwise and same value. – old_timer Dec 30 '18 at 16:52
  • @old_timer: C++ `==` applied to floating-point operands compares for numerical equality, not bit-patterns. IEEE 754 has always specified that its numerical operations (including comparison for numbers, not NaNs) are based on the value, not the bit pattern. From the 1985 version: “This standard allows an implementation to encode some values redundantly, provided that redundancy be transparent to the user in the following sense: an implementation either shall encode every nonzero value uniquely or it shall not distinguish redundant encodings of nonzero values.” – Eric Postpischil Dec 31 '18 at 02:47
  • @old_timer: The root of the “don’t use equals” issue is that floating-point results derived by different methods that would be identical if computed with exact mathematics often produce non-identical results when computed with limited precision (e.g., adding the same numbers in different orders produces different results). It does not come from mishandling different ways to represent the same value; if a value is represented in `x` as 1.00•10^2 and in `y` as 100.•10^0, then `x == y` should be true and generally is in common implementations. – Eric Postpischil Dec 31 '18 at 02:50
  • @old_timer: The fact that `1.1f` and `(float) 1.1` produce the same **result** is not relevant to the fact that `1.1` and 1.1f` do not **represent the same value**. Assuming IEEE-754 64- and 32-bit binary are in use with round-to-nearest, then the object produced from `1.1` in source code represents 1.100000000000000088817841970012523233890533447265625, and the object produced from `1.1f` in source code represents 1.10000002384185791015625. That is `1.1` and `1.1f` **do not** produce the same value (with or without different bit patterns). – Eric Postpischil Dec 31 '18 at 02:54

2 Answers2

4

You've wandered into an interesting area of almost all programming languages. Floating point values are tricky things, and testing them for equality is very rarely recommended. The basic problem is that floating point values on modern computers are represented as binary decimals with a finite number of digits of precision.

To make this simpler to understand, lets work with base 10 decimals and use a number that can't be accurately represented using them. Take 1/3. If you are representing it as a base 10 decimal you get this:

0.̅3 (there is a bar over the three if it isn't showing up properly). Basically, it goes on forever, there is no finite number of digits that can represent 1/3 as a base ten decimal with perfect accuracy. So, if you only have so many digits, you chop it off and approximate:

0.333333

That's actually 333333/1000000, which is really close to 1/3, but not quite.

C++ has a few different floating point types. And these types usually (it depends on the platform the program is being compiled for) have different numbers of significant digits. By default, a floating point constant is of type double which usually has more digits than a float (and it never has less). Again, using base 10 as an example, since you were storing your value in a float you were doing something like this:

0.333333 == 0.3333333333333333333

which of course is false.

If you wrote your code this way:

#include <iostream>
using namespace std;
int main()
{
      float x = 1.1f;
      if(x == 1.1f)
         cout<<"yes";
      else
         cout<<"no";
      return 0;
}

you would likely get the expected result. Putting an f at the end of a bare floating point value (aka, a floating point literal) tells C++ that it's of type float.

This is all very fascinating of course, and there's a lot to get into. If you would like to learn a lot more about how floating point numbers are really represented, there is a nice Wikipedia page on IEEE 754 floating point representation, which is how most modern processors represent floating point numbers nowadays.

From a practical standpoint, you should rarely (if ever) compare floating point numbers for equality. Usually, a desire to do so indicates some sort of design flaw in your program. And if you really must than use an 'epsilon' comparison. Basically, test to see if your number is 'close enough', though determining what that means in any given situation isn't necessarily a trivial task, which is why it usually represents a design flaw if you need to compare them for equality at all. But, in your case, it could look like this:

#include <iostream>
#include <cmath>
using namespace std;
int main()
{
      float x=1.1;
      if (fabs(x - 1.1) < 0.000001)
         cout<<"yes";
      else
         cout<<"no";
      return 0;
}
Omnifarious
  • 54,333
  • 19
  • 131
  • 194
  • 3
    Please do not generally recommend using an “epsilon” comparison. There are few situations where it is a proper solution. See [1](https://stackoverflow.com/a/21715937/298225) and [2](https://stackoverflow.com/a/5629905/298225), among other answers, for reasons it is often not a proper solution. Often, better advice for somebody attempting to compare floating-point results for equality is to reconsider their software design. Your phrase “whatever that means” is a big clue that correct meaning is absent. – Eric Postpischil Dec 30 '18 at 10:17
  • @EricPostpischil - You're right. I was very consciously trying to keep this answer to being one that even a beginner could understand, since it seemed like it was a beginner who was asking the question. – Omnifarious Dec 30 '18 at 22:32
3

The reason the compare fails is that you're comparing a double value to a float variable.

Some compilers will issue a warning when you assign a double value to a float variable.

To get the desired output, you could try this:

double x = 1.1;
if (x == 1.1)

or this:

float x = 1.1f;
if (x == 1.1f)
Sid S
  • 6,037
  • 2
  • 18
  • 24
  • 1
    A better answer is to tell the OP to just not ever compare for equality when using floating point numbers. I mean, what you suggest will almost certainly work, but it's very specific to this situation. – Omnifarious Dec 30 '18 at 04:25
  • what is difference between 1.1 and 1.1f – hrishi007 Dec 30 '18 at 04:26
  • 1
    `1.1` is a `double`, `1.1f` is a `float` – Sid S Dec 30 '18 at 04:27
  • 1
    You should almost never compare floating point using `==` – Slava Dec 30 '18 at 05:13
  • @Slava, So ? The OP was asking why his comparison didn't work. That's what I answered. – Sid S Dec 30 '18 at 05:39
  • @SidS you also suggest to compare them using `==` which is bad advice – Slava Dec 30 '18 at 05:50
  • 1
    @Slava, I pointed out *how* to get `==` to work, as he asked why `==` didn't work. *"You shouldn't use =="* is not a good answer to why `==` doesn't work. – Sid S Dec 30 '18 at 06:07
  • 1
    Sometimes answering a question requires correcting the mistaken assumption behind a question. Simply giving the person a direct and simple answer to their question is, while technically correct, not a good answer. – Omnifarious Dec 30 '18 at 06:11
  • 2
    @Omnifarious, Sometimes, simply giving a person a direct and simple answer to their question is all it takes for them to understand the problem they were facing. – Sid S Dec 30 '18 at 06:12
  • @SidS - That's true. But probably not in this case. And even if it were true, I could easily see a person who was relatively new to C++ or programming in general who got the idea that maybe different types never compare equal or some other similar wrong impression from your answer. I'm not trying to attack you. I voted your answer up. I'm trying to help you. – Omnifarious Dec 30 '18 at 06:21