1

I had a question regarding a type conversion error I encountered whilst solving a question (link at the bottom). The only difference between my AC submission and my WA submission is that in the first submission I typecasted to a double rather than a float. I would highly appreciate any clarification on why float gives an error. Thank you.

WA Submission:

#include<bits/stdc++.h>
using namespace std;

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        long long int a,b,c,d;
        cin>>a>>b>>c>>d;
        if(a<=b)
            cout<<b<<endl;
        else
        {
            if(d>=c)
                cout<<-1<<endl;
            else
            {
                long long int val = c - d;
                long long int f = ceil((a-b)/((float)val));
                cout<<(b + (c * f))<<endl;
            }
        }


    }
    return 0;
}

AC Submission

#include<bits/stdc++.h>
using namespace std;

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        long long int a,b,c,d;
        cin>>a>>b>>c>>d;
        if(a<=b)
            cout<<b<<endl;
        else
        {
            if(d>=c)
                cout<<-1<<endl;
            else
            {
                long long int val = c - d;
                long long int f = ceil((a-b)/((double)val));
                cout<<(b + (c * f))<<endl;
            }
        }


    }
    return 0;
}

Question

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
  • 2
    What does WA / AC mean? – Holt May 17 '20 at 13:00
  • WA: Wrong Answer, AC: Accepted. – Ashish Tuteja May 17 '20 at 13:01
  • 2
    Well, `double` has more precision than `float`, so that's not surprising, I did not look at the question entirely but the inputs go up to 10e9, and `float` cannot store such numbers exactly, while `double` can. But you probably don't need to cast anything here. – Holt May 17 '20 at 13:03
  • 1
    Also, not related to your issue, but avoid [`using namespace std;`](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) and do not use [`bits/stdc++.h`](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h). – Holt May 17 '20 at 13:07
  • 1
    @Holt using namespace and the all-inclusive header is often used in coding competitions to save time. Also, the disadvantages of using them rarely apply to them. – Empty Space May 17 '20 at 13:16
  • 1
    @MutableSideEffect I know, but since a lot of people doing these competitions are beginners, it teaches bad practices, so it's never a bad thing to explain it. – Holt May 17 '20 at 13:18
  • @Holt that's true, agreed. – Empty Space May 17 '20 at 13:22

2 Answers2

1

You need to understand that calculations involving decimal numbers result in some error if the final number is recurring or has very long fractional part (eg. 1.000000000078). Since, double is of 2x precision it is able to handles these errors (mostly rounding errors). Try to use long double instead in these contest questions.

Also, this might help.

Manav Chhibber
  • 678
  • 3
  • 16
  • 1
    `the final number is recurring or irrational` which number are you referring to? 1) (float)val is an integer which implies it cannot be irrational or recurring. 2) The precision of the result of the division is not important since we apply a ceiling and a precision of one decimal digit is sufficient. The precision of (float)val matters but not because it is recurring or irrational. – Empty Space May 17 '20 at 13:23
  • @MutableSideEffect 1) number after dividing 2) I don't agree, e.g. lets A=(a-b), B=(val), res1=A/(float)B, res2=A/(double)B , for A=595196166 and B=595196161 this would result in res1=1 and res2=1.0000000084005917777574... having that much precision is not possible for float so it rounds res1 to 1. Hope that helps. – Manav Chhibber May 17 '20 at 14:10
  • @MutableSideEffect yeah you're right about irrational numbers, my mistake, editting it. – Manav Chhibber May 17 '20 at 15:13
1

Double has a higher precision so it can store larger values, also you can use long long instead of long long int(it is the same thing but long long is shorter so it looks cleaner), and you dont need to write that much if statements, just use else if

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        long long a,b,c,d;
        cin>>a>>b>>c>>d;
        if(a<=b)
            cout<<b<<endl;
        else if(d>=c)
            cout<<-1<<endl;
        else
        {
            long long val = c - d;
            long long f = ceil((a-b)/((double)val));
            cout<<(b + (c * f))<<endl;
        }
    }
    return 0;
}
SzymonO
  • 432
  • 3
  • 15