2

Assume you're given this excerpt of code:

Example 1:

printf("Enter two real numbers: ");
scanf("%f %f", &a, &b);

if (a == b) //do something

My question is: Is it necessary to use some "safety measures" when comparing floats directly taken from keyboard?

For instance if I'm given the similar code:

Example 2:

printf("Enter two real numbers: ");
scanf("%f %f", &a, &b);
float x = a / b + 2 * a / 3;
float y = b / a + 3 * a / 2;
if (x == y) //do something

I know I should be using:

fabs(x - y) < RefValue

for if's condition just to avoid potential occurence of false even if the result should be true. But do I have to do so in Example 1, too?

Stargateur
  • 24,473
  • 8
  • 65
  • 91
tyr
  • 139
  • 7

2 Answers2

4

It's pretty safe to assume that two numbers entered from the keyboard using the same input method in the exact same character representation end up as the same binary number. This has absolutely nothing to do with precision - After all, that's reproducibility, one of the most inherent traits of computer programs we rely on. The two numbers might be imprecise and not exactly represent the input, but they must be identical. In short, your Example 1 is valid.

It's even possible (but not guaranteed) that different character representations end up at the same binary number, which would be caused by the fact that not all decimal numbers have an exact representation in the internal FP format. That would not affect your comparison, though, as there is not much you can do about that except using a different internal representation.

tofro
  • 5,640
  • 14
  • 31
0

There's nothing about taking a float from the keyboard that makes it inherently less precise than any other float. Having said that, in taking a float from the keyboard, you run the risk of two numbers that are different being stored as the same value as the difference between the two numbers is less than the epsilon for single precision floats. However, this is no different from any other usage of floats. In summary, a float acquired from scanf is no different than any other float, and any safety measures you would or wouldn't normally use should be used with these floats as well.

Eli Sadoff
  • 7,173
  • 6
  • 33
  • 61
  • So it's not the calculations that "ruin" the precision, it's the way float is stored? – tyr Oct 29 '16 at 14:33
  • 2
    Floats are inherently imprecise (see [here](http://stackoverflow.com/questions/588004/is-floating-point-math-broken?rq=1)) so this will be an issue regardless of how the float is gotten. – Eli Sadoff Oct 29 '16 at 14:35
  • 2
    ( 1/3 == 0.3333) is an entirely different thing than entering the same number twice from the keyboard. The former is based on the assumption that two different ways of expressing a number end up with equality, the latter is running the same piece of program twice on the same input - Which **must** produce the same results (even if they are equally imprecise). – tofro Oct 29 '16 at 14:38
  • @tofro that was my reasoning, too. #confused_now – tyr Oct 29 '16 at 14:40
  • @tofro I didn't say anything that contradicted that, no? – Eli Sadoff Oct 29 '16 at 14:41
  • At least you managed to confuse the OP with "so this will be an issue regardless of how the float is gotten" in your comment. No, it's not. – tofro Oct 29 '16 at 15:00
  • "... difference between the two numbers is less than the epsilon for single precision floats" --> no. Epsilon is a proportional or relative factor, not an absolute one as suggested by this answer. – chux - Reinstate Monica Oct 29 '16 at 15:02
  • @chux There is an IEEE 754 defined machine epsilon which is the upper bound of epsilon. While epsilon is a relative value, the machine epsilon (in this case `1.19e-07` for a signed `float`) is a good guideline as that is the upper bound for epsilon. – Eli Sadoff Oct 29 '16 at 15:03
  • 1
    It is not a question of the value of epsilon (The difference between 1.0f and the next value), it is how this answer suggests using it, as a _difference between the two (FP) numbers_. `1e30` and `nextafterf(1e30, 1e31)` differ by 1 ULP, yet have a difference far greater than `1.19e-07`. `1e-30` is a 1000x times than `1e-27` yet their difference is far less than `1.19e-07`. – chux - Reinstate Monica Oct 29 '16 at 15:10