2

I tried the below code i assigned a float value to variable and i compared it with a floating point value but it did not gave the desired output. Here as a==13.30 is true i thought it will print "a" instead it prints "5"

#include<iostream>
using namespace std;
int main()
{
    float a=13.30;
    if(a==13.30)
    cout<<a;
    else
    cout<<"5";

}

output is "5" not "a"

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
Subbu
  • 21
  • 3
  • 2
    You can, it's just that `13.30` is a `double`, and closest `double` to `13.30` is a different number to the closest `float` to `13.30f`. In other words `if(a==13.30f)` would work, or declare `a` as a `double`. – Bathsheba Apr 10 '20 at 16:40
  • Worth stating that floating point numbers should never be checked for equality anyway; it should be checked for being in an acceptable viable range. – sweenish Apr 10 '20 at 16:49
  • @sweenish -- "nearly equals" (i.e., within an acceptable range) introduces its own set of problems. It's not transitive. – Pete Becker Apr 10 '20 at 20:01
  • It's less broken than direct equality comparison of floating point types, though. – sweenish Apr 10 '20 at 20:04
  • 1
    Subbu, Print out `a` and `13.30` with at least 20 digits to gain insight why the two are different. Once you see they are different, and neither is 13.30, it is simply to see why they are not equal. Now the next question you may ask is why is neither 13.30? – chux - Reinstate Monica Apr 10 '20 at 22:07

2 Answers2

8

13.30 is a double. Try comparing against 13.30f.

0.30 cannot be represented exactly and since double has a higher precision, it is not an exact match.

rustyx
  • 80,671
  • 25
  • 200
  • 267
  • Specifically, assuming IEEE754 arithmetic, 13.3 double is 13.300000000000000710542735760100185871124267578125. 13.3f is 13.30000019073486328125. – Patricia Shanahan Apr 11 '20 at 03:12
0

Ofcourse you can simply compare float value with some numerical value , but just because you can , it doesn't mean you should. It's classical example of that . There are many problems regarding storing exact floating point value in memory , due to hardware restrictions , this issue regarding storing exact floating point value in memory exist in virtually all the programming languages and platform . A better way to equating floating point values is checking if the difference of two values that you need to compare is less than some other very small number . In your code , you can implement that as ,

#include <iostream>
using namespace std;
const double EPSILON = 1e-5;
int main()
{
  float a = 13.30;
  if (abs(a - 13.30) < EPSILON)
    cout << a;
  else
    cout << "5";
}

Now , this code will output 13.30 , here EPSILON is used as a very small double value to compare with the difference . To know more about why this issue is prevalent read , Is-floating-point-math-broken and Why are floating point numbers inaccurate

parth_07
  • 1,322
  • 16
  • 22
  • This "nearly equals" comparison does not behave the way people expect equality comparisons to work. In particular, if `a` "nearly equals" `b` and `b` "nearly equals" `c`, it does not follow that `a` "nearly equals" `c`. – Pete Becker Apr 10 '20 at 19:59
  • @PeteBecker yeah , it dont exactly follow a "nearly" equals c , but nevertheless , it is still a quick work around for this situation and a famous enough technique that i thought could be helpful here . – parth_07 Apr 10 '20 at 20:08
  • Without expressing why `1e-5` is a reasonable epsilon, the answer simply leads to another problem. Had `a` been `13.30e20f`, an epsilon of `1e-5`, would have had no benefit over OP's code. Had `a` been `13.30e-30`, the `if()` would be true for far too many no-so-near answers. Floating point numbers are distributed logarithmically. Any epsilon test deserves to take that into account. `1e-6f`; would have been better for `13.30f`. – chux - Reinstate Monica Apr 10 '20 at 22:26
  • @chux-ReinstateMonica there wasn't enough details given in the question to decide what should be the range of the EPSILON . I was just illustrating a quick work around regarding the situation , and knowing the work around , it is easy to understand that EPSILON should be much smaller than either of the value that we are comparing . That being said , i know this method is far from ideal , but it think it can still be fairly useful for many situations – parth_07 Apr 11 '20 at 00:34