Live data from Hacker News

Test if a number is even

ubuntuincident.wordpress.com

41–50 of 68 posts

Re: Test if a number is even

#41
It may be worth pointing out: these are equivalent comparisons when testing for even numbers but cannot be extrapolated to testing for odd numbers. The reason being that a negative odd number modulus 2 is -1, not 1.

So `n % 2 == 1` should probably [1] be replaced with `n % 2 != 0`.

While this may be obvious with experience, if the code says `n % 2 == 0`, then a future developer who is trying to reverse the operation for some reason must know that they need to change the equality operator not the right operand. Whereas, with `n % 1 == 0`, they can change either safely and get the same result.

This feels problematic because the business logic that necessitated the change may be "do this when odd" and it may feel incorrect to implement "don't do this when even".

I really disfavor writing code that could be easily misinterpreted and modified in future by less-experienced developers; or maybe just someone (me) who's tired or rushing. For that reason, and the performance one, I try to stick to the bitwise operator.

[1] Of course, if for some reason you wanted to test for only positive odd numbers, you could use `n % 2 == 1`, but please write a comment noting that you're being clever.

Re: Test if a number is even

#42
post #41

It may be worth pointing out: these are equivalent comparisons when testing for even numbers but cannot be extrapolated to testing for odd numbers. The reason being that a negative odd number modulus 2 is -1, not 1. So `n % 2 == 1` should probably [1] be replaced with `n % 2 != 0`. While this may be obvious with experience, if the code says `n % 2 == 0`, then a future developer who is trying to reverse the operation…

You can just not( iseven() )

Re: Test if a number is even

#43
post #21
post #6

Optimizing compilers have been able to recognize pretty complicated patterns for many years. For instance if you're making a loop to count the bits that are set in a number, the compiler can recognize the entire loop and turn it into a single popcnt instruction (e.g. https://lemire.me/blog/2016/05/23/the-surprising-cleverness-... )

They've been able to recognize this pattern since the 1960s (popcount is a very historically special case and not really a sign of complexity, since traditionally it was "if you write this exact code from the documentation, you'll get the machine instruction" and didn't imply any more general cleverness.)

Yeah, once I tried writing out a dumber popcount loop (checking each bit) for better readability, and was annoyed to find that GCC and Clang didn't recognize it. I ended up looking into the source of both compilers to find that they only transform the more 'idiomatic' version.

Re: Test if a number is even

#44

Earlier quoted context omitted.

Maybe one day there will be compilers that can choose what to optimize based on their aesthetic judgement of the code. I could see that as a novel feedback mechanism for software engineers. As it stands, I'm glad they design optimizations abstractly, even if that means code I don't like gets the benefits

It's not about aesthetics, but about the sort of hit-rate of the optimisations as if they need to be too smart to figure things out, then it also means that they'd more rarely be used and necessary.

I'm not quite sure what you're visualizing for compilers, if I understand correctly, what I'd say is:

tl;dr: there are general optimizations for "this function in a for loop is a constant expression, we dont need to call it 500 times"

or

"this obscure combination of asm instructions is optimal on pentium iii 350 mhz dual core"

not "we need to turn this unholy CS101 student spaghetti code where they do a 500 branch-if into a for loop"

comment over here is attempting to communicate that as well https://news.ycombinator.com/item?id=42705758

I've never, ever, heard the idea that compilers are burdened by the workload of maintaining thousands of type-specific optimizations for hilariously bad code, until today. I've been here since 2009, so it is puzzling to me to see it referred to off hand, in a "this is water" manner https://en.wikipedia.org/wiki/This_Is_Water

Re: Test if a number is even

#45
post #28

Does the C compiler optimise out the branch from the if() statement? I'd write it more like this: int main(int argc, char **argv) { int total = 0; for (int i=2147483647; i; --i) { total += i & 1; } printf("%d\n", total); return 0; }

> Does the C compiler optimise out the branch from the if() statement?

In a function as simple as this, the existence of a branch may be as fast or faster than a version without as the CPU has the opportunity to eliminate register/memory modification via branch prediction.

So even if a compiler does not optimize out this particular if construct, there is a good chance the CPU will.

Re: Test if a number is even

#47
post #21
post #6

Optimizing compilers have been able to recognize pretty complicated patterns for many years. For instance if you're making a loop to count the bits that are set in a number, the compiler can recognize the entire loop and turn it into a single popcnt instruction (e.g. https://lemire.me/blog/2016/05/23/the-surprising-cleverness-... )

They've been able to recognize this pattern since the 1960s (popcount is a very historically special case and not really a sign of complexity, since traditionally it was "if you write this exact code from the documentation, you'll get the machine instruction" and didn't imply any more general cleverness.)

popcount is a very historically special case

To elaborate a bit on the specialness of popcount: It is a generally accepted belief in the computer architecture community that several systems included a popcount iNstruction Solely due to A request from a single "very good customer".

Re: Test if a number is even

#49
post #41

It may be worth pointing out: these are equivalent comparisons when testing for even numbers but cannot be extrapolated to testing for odd numbers. The reason being that a negative odd number modulus 2 is -1, not 1. So `n % 2 == 1` should probably [1] be replaced with `n % 2 != 0`. While this may be obvious with experience, if the code says `n % 2 == 0`, then a future developer who is trying to reverse the operation…

I really disfavor writing code that could be easily misinterpreted and modified in future by less-experienced developers

That's their problem. Otherwise you're just contributing to the decline.

Re: Test if a number is even

#50
post #28

Does the C compiler optimise out the branch from the if() statement? I'd write it more like this: int main(int argc, char **argv) { int total = 0; for (int i=2147483647; i; --i) { total += i & 1; } printf("%d\n", total); return 0; }

You inverted the condition and the loop doesn't go to 0, so that's not functionslly the same code.
Post reply on HN