0

This is the link for the problem that I was trying to solve: https://www.codechef.com/problems/HS08TEST

It's a pretty straightforward problem with just three scenarios so I was sure that the code would run. However, I got the wrong answer message (the website doesn't show what has gone wrong). My code is as follows :

#include<bits/stdc++.h>

using namespace std;

double w, b;

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> w >> b;
    cout << fixed;
    if(fmod(w, 5) == 0.0 && w <= b)
        cout << setprecision(2) << (b - w) << "\n";
    else
        cout << setprecision(2) << b << "\n";
}

The solutions which were marked as correct by the site did a rather odd thing : (w+0.5)<=b Their claims (Without explanation) were that if we don't put the 0.5 part in, <= returns a -ve result. Can someone explain what is the exact issue here?

EDIT

Due to floating point precision issues, I was advised to add 0.5 so that the computer can perform the comparison. Now according to maths a<b is the same as a+c<b+c (Inequalities). I used that principle to write (w+0.5)<=(b+0.5). However,even this gives a Wrong Answer Message ! The code used :

#include<bits/stdc++.h>

using namespace std;

double w, b;

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> w >> b;
    cout << fixed;
    if(fmod(w, 5) == 0.0 && (w+0.5) <= (b+0.5))
        cout << setprecision(2) << (b - w) << "\n";
    else
        cout << setprecision(2) << b << "\n";
}
  • Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Quimby Aug 05 '21 at 06:53
  • Umm.....well it explains, but I required a solution to overcome this. And also, if _floating point_ is broken, why does ```(w+0.5)<=b``` work ? it's floating point as well. – Aritro Shome Aug 05 '21 at 07:04
  • 1
    Please read the answer, the math is of course not broken, just the precision is finite. It works because the `+0.5` provides a margin for the error. You typically get things like `1.0000001` (extra rounding at the last decimal place) which strictly speaking is not `<=1` but you want it to be. `+0.5`, although much larger, serves the role of typically used epsilon. – Quimby Aug 05 '21 at 07:07
  • As for a solution, it's not that easy - see [these answers](https://stackoverflow.com/questions/17333/what-is-the-most-effective-way-for-float-and-double-comparison). – Quimby Aug 05 '21 at 07:09
  • @Quimby The edit follows the suggestions in the answers, still doesn't work. – Aritro Shome Aug 06 '21 at 03:57
  • You cannot add 0.5 to both sides, the whole point of the "brokeness" is the limited precision and adding `0.5` compensates for the error. Where exactly did you get the suggestion? Understand that `0.1 + 0.2 == 0.3` is `false`. Why? See [this answer](https://stackoverflow.com/a/27030789/7691729). – Quimby Aug 06 '21 at 07:39
  • 0.5 is the transaction fee mention in the question. You have to take care of the transaction fee on the condition. Another way to do it is w <= b - 0.5 exlclude the transaction fee from the balance. – MIARD Aug 06 '21 at 21:27

2 Answers2

2

This happens because of some rounding error. When comparing two floating-point or double values, we must take the precision into account. For instance, if two numbers are 3.1428 and 3.1415, they are identical up to a precision of 0.01, but not beyond that, such as 0.001. You can get more information here. You can also search for rounding errors.

MIARD
  • 126
  • 1
  • 7
1

In the problem, there is a condition like, " For each successful withdrawal the bank charges 0.50 $US". If you have 5$ in your account you cannot withdraw 5$. You can withdraw 5$ - 0.50$ = 4.50$ as you have to keep 0.05$ for transaction fee. It needs to be assured before withdraw that you have a transaction fee left in your account. So we have to check withdraw + 0.5 <= balance. Here, 0.5$ for the transaction fee. w <= b or w + 0.5 <= b + 0.5 will give the wrong answer because when you have a 5$ balance and you are going to withdraw 5$ it will be accepted according to the condition. Without the transaction fee, one cannot withdraw. Therefore, we have to add 0.5 with the withdraw when checking. Another way we can do it is w <= b - 0.5, excluding transaction fees from the account balance.

MIARD
  • 126
  • 1
  • 7