- I fell into a very interesting situation today , while solving CF — 599D.
- say long long a = 1000000000000000363,b= 91
- I wrote long long c = ceil(a*1.0/b) thinking (long * double) / double should be perfect double and ceil(double) — should work out.
- I was expecting correct answer, c = 10989010989010993, but it produced c= 10989010989010994 , 1 more than the actual — result!!!! Damn to the precision issue.
Lesson :
-
- Option 1 : Study lot lot and lot about your compiler and how it manages precision while both implicit and explicit cast.
-
- Option 2 : Use your own ceil function like this
- template inline T ceil(T numerator ,T denominator)
- {
- return (numerator+denominator-1)/denominator;
- }
Moral : Avoid fraction as much as you can.
Yes, doing (num + den - 1) / den is what I always do. You only have to be careful with overflow if working with very big numbers, in which case you should do
return num%den == 0 ? num/den : num/den + 1
. The last option is more expensive because of the modulo operation, so I only use it in case of possible overflow.Ya, good reminder... :)
Not necessarily slower due to modulo. On x86 div instruction returns both quotient and reminder, so modulo operation comes for free as you need to do division anyway. GCC does this optimization. Only additional cost comes from the conditionally adding + 1. It can be compiled to something like this:
On other architectures reminder can be obtained by doing multiplication of division result. In either case it is not as expensive as doing completely unrelated modulo operation.
Any specific problem where overflow occurs? People also suggest the same in binary search. If some problem related to that?
Doubt has been cleared.
I have edited this comment because some people find it inappropriate.
If you are still curious you can check the 1st version of this comment.
I assume you want somebody to give you a hack for problem A of the most recent educational round. I'm not sure about rules regarding collaboration for hacks but this seems very sketchy. In any case you can just wait until the round is over, and then view the hacks.
Also, there's basically no point in hacking at this stage. The ceil hack tests will be added to system tests so any solution you'd be able to hack would just FST anyways.
Thanks buddy for replying. I searched over some more blogs and got the answer to my doubt. Also I know that hack tests are added in the final test set and me hacking every single solution involving ceil function make no sense. It was just for knowledge purpose. I really appreciate the fact that you respect codeforces' rules and so does I.
I myself once encountered the same problem while using ceil function in some round (may be educational) and I could not find the exact reason at that time. That time I only understood that ceil function should be avoided.
Just because of the last educational round I knew that some people are going to land on this blog :-) so I asked my doubt.
Yeah right. Always assume malicious intent.
I landed here because my solution got hacked and not because I want to hack anybody.
I realize that I did come off a bit rude in my original comment and I'm sorry about that.
But my point about the ongoing hacking phase still stands.
Now can u please explain?
It appears in this contest that most hacks were not because of lack of precision in doubles, but because C++ prints large double integers in scientific notation instead of exact (e.g.
1e+09
instead of1000000000
). Indeed, it seems as long as you cast your final answer toint
, then your solution will pass.Example 1: https://mirror.codeforces.com/contest/1476/submission/105885372
Example 2 (Java): https://mirror.codeforces.com/contest/1476/submission/105949234
Example 3 (even
float
had enough precision for this problem!): https://mirror.codeforces.com/contest/1476/submission/105859728That being said, I still wouldn't recommend doubles :P, just use integer division whenever possible.
No need to apologise. To be honest my original comment to some extent did seem like someone asking for a hack case. I should have mentioned not to reply before 10 hours or something. If I would have seen such a comment probably I would have also thought about it in the same way.