1) Is this unoverflowable?
long long v1, v2, result;
[..]
result = ((long double) v1 / v2) * 1000000LL;
1.a) Can I leave out the LL on the constant? And why.
2) Alternatively is this variation without a float ok?
long long l1, l2, result;
[..]
result = (1000000 * (v1 / v2) + v1 % v2);
2.a) Which has more overheads? The 1st开发者_开发知识库 or this example?
3) Can floats ever overflow, or just wrap to 'sane' values?
Yes, the result in example (1) could easily overflow if, say, v1 = 1000000000000000 and v2 = 1. You don't need the LL on that constant because it is small enough to fit into an int
(under most implementations, in any case).
(2) That can overflow just as well as example 1 if v1 and v2 are as I have given them.
The first example is more expensive as floating point arithmetic is more expensive than integer arithmetic.
(3) Floats may certainly overflow and the consequences are implementation dependent.
As Arjit has pointed out, you can prevent an overflow by checking the value of v1 before performing the calculation. If v1 could be negative you would also need to check the negative version, and perhaps the following might be better...
if ((LONG_LONG_MAX / 1000000) > V1)
{
...
}
If you are really up against the limit you could give yourself a little more headroom by declaring the variables to be unsigned
.
Later - edit to correct mistake pointed out by Arjit.
Firstly
- if doing INT or Long calculation dont involve float to it. Because Your result in First part would have many different values which are nearly equal.
Because (float)v1/v2 = ab.cdef. // where cdef can vary.
Your second implementation can also cause overflow if v1 = 2^15 and v2 = 1
so if you are looking for overflow and security you should always check
like 2^18/Constant which is 1000000 in this case
so
if(2^18/Constant > v1)
result = (1000000 * (v1 / v2) + v1 % v2);
This would be any hack proof.
Hope This helps
精彩评论