Andrew Poelstra wrote On 05/30/06 17:36,:
Andrew Poelstra said:
[...]
Why does it tell me that -42 is not divisible by 3?
Because it is adding ~3, and in general bit twiddling is undefined
when working with negative integers. I should have caught that.
int n; should be unsigned int n;, or a better solution would have
been to set n to abs(n) right before the while loop.
And if n == INT_MIN?
You would need to check for that, and then add three to ensure that you
don't overflow when you abs() it.
Any other special cases I should know about?
Only two that I can think of off-hand, both having
to do with issues of representation. Hint #1: Is the
absolute value of ~3 greater or less than a thousand?
Hint #2: Is the value of ~3 even or odd? (See section
6.2.6.2, paragraph 2).
The principal lesson is that it is usually silly to
use "bit fiddling" for tasks of the kind posed by the
O.P. (more likely, by the O.P.'s homework assignment).
As this thread demonstrates, such tasks can be trickier
than they might appear, and the "obvious" solutions have
pitfalls. Avoiding the pits can consume more execution
time than you save by avoiding the % or the * or whatever.
Let's try to imagine a scenario where speeding up a
divisibility-by-three test would make a useful improvement.
On the six-year-old machine sitting in front of me at the
moment, it takes about 0.172 seconds to test a million
numbers for divisibility by three using the % operator.
By resorting to bit fiddling I can cut the time to just
0.013 seconds, better than a thirteenfold speedup. Wow!
... but how much "Wow" is warranted? To save just one
second of the program's total execution time, I'd need to
use the faster method on about six and a half million
numbers. Six and a half million divisible-by-three tests,
and I save one, yes folks, a whopping ONE second. If it
took me, say, one minute to write the code and convince
myself I hadn't botched it, I'd break even after my program
had done three hundred eighty million divisibility tests --
until that moment, I'm running in the red.
How badly do you need three hundred eighty million
divisible-by-three tests?
Now, there can be circumstances where micro-optimization
of this sort is warranted. I maintain, though, that it is
NEVER warranted before convincing evidence has been found
that it is necessary.