-2

Why do the following not equal each other?

0.37024025

and

(sqrt(2)*M_PI/3)*(1/4)

I see significant divergence in my solution, but all I did was place a number with the formula behind it.

Ben
  • 332
  • 1
  • 3
  • 13

2 Answers2

3

The expression (sqrt(2)*M_PI/3)*(1/4) has integer division. Namely, (1/4) is always going to be zero, making the entire expression zero since it's multiplied by that.

(sqrt(2.0)*M_PI/3.0)*(1.0/4.0);

Is a little bit closer to what you wanted, but when comparing doubles exactly I'd use an epsilon threshold and test if both are "close enough" to each other based on that:

bool cmp(double d1, double d2, double epsilon)
{
    return std::fabs(d1 - d2) < epsilon;
}
Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
  • 1
    You've gone overboard on your corrections. sqrt(2) works fine because the argument to the function is a double and the integer 2 will be passed in as a double. `M_PI/3` works fine because of promotion, the numerator is a double so the denominator will be promoted to a double and double-precision division will be performed. The only expression that doesn't work as was intended is `1/4` because they are both integers and integer division is applied resulting in 0. – Wyck Feb 05 '19 at 17:24
  • @Wyck I'm aware that `M_PI` promotes the division to `double`, and that `sqrt` returns a `double`; I just like to be explicit about my intent in my code – Govind Parmar Feb 05 '19 at 17:26
  • 1
    there is more to comparing floating points than adding the epsilon. You also have to be aware that many properties that one would expect dont hold for such a comparsion, most obviously it is not safe to assume that `cmp(a,b) && cmp(a,c)` implies `cmp(b,c)` – 463035818_is_not_an_ai Feb 05 '19 at 17:29
  • 1
    Yeah, I think that's probably the corrective technique we all end up adopting in practice. Appreciation of the nuances of why it works sometimes and not all the time is important though. – Wyck Feb 05 '19 at 17:29
  • An absolute epsilon like this also tends to be iffy. You have to know the approximate magnitude of the values a-priori for it to make sense. – Max Langhof Feb 05 '19 at 17:50
  • @MaxLanghof Well, I did leave it as a parameter to `cmp` so that it can be filled in arbitrarily at the call site. – Govind Parmar Feb 05 '19 at 17:51
1

You're performing integral division with 1/4 which will result in 0, not 0.25. Try adding a .0f or .0 suffix for float or double, respectively.

Mark Ingram
  • 71,849
  • 51
  • 176
  • 230