How to invert a boolean
-
Just found this line of C code:
blink_mode = (++blink_mode) & 1;
What's wrong with a simple "blink_mode = !blink_mode"?
-
I once did this
pause = (pause) ? false : true;
at 3 AM. I spent 3 minutes the following day staring at it trying to figure out why I did it that way before fixing it.
-
I don't suppose there's any chance that blink_mode could ever be set to a value other than 0 or 1, is there?
Also, it occurs to me that, depending on the CPU and how smart the compiler is, x = (++x) & 1 could possibly produce slightly faster code than x = !x, precisely because it doesn't have to treat all non-zero values as true. (In particular, on some architectures C-style boolean negation might require a branch.) Of course, that would be a completely pointless optimization unless that line of code just happened to be part of the critical innermost loop that your CPU-bound program spends 99% of its time in. And besides, x ^= 1 ought to be even faster anyway.
-
@vyznev said:
Shouldn't make the least bit of difference to anyone's choice of algorithm though; either method, ! or ++&1, will immediately normalise it into the 0/1 range after the first iteration.I don't suppose there's any chance that blink_mode could ever be set to a value other than 0 or 1, is there?
-
@MadnessASAP said:
I once did this
pause = (pause) ? false : true;
at 3 AM. I spent 3 minutes the following day staring at it trying to figure out why I did it that way before fixing it.
That's just being future-proof.
Suppose you want
pause
to be alwaystrue
.
You just have to change the code to:pause = (pause) ? true : true;
<font size="1"></sarchasm> </font>
-
On top of that, blink_mode is assigned twice in the same statement, which means the result is actually indeterminate.
-
Unless you're using a system where NULL isn't 0 or 1, and a ! wouldn't normalize it either way...
-
@ZPedro said:
On top of that, blink_mode is assigned twice in the same statement, which means the result is actually indeterminate.
ROFL, totally overlooked that, but of course it should have been i = (i +1) & 1 if it was to make any sense at all.
-
The most obvious reason, which no one has mentioned yet, is that a negation may include a test-and-jump sequence (which can be very costly), but the algorithmic version can be executed by the CPU without guessing execution paths.
Old-timer hardcore C programmers tend to avoid if:s at any opportunity.
-
@ZPedro said:
On top of that, blink_mode is assigned twice in the same statement, which means the result is actually indeterminate.
Not really, but only because this is a particular special case. Stating the exact nature of the special case would, however, take more space than I have in this margin.
-
@tgape said:
@ZPedro said:
Perhaps you're balking at the word "indeterminate" when the terminology is "undefined", but this isn't a special case and the result cannot be determined in advance simply by looking at the code and making assumptions: http://c-faq.com/expr/ieqiplusplus.htmlOn top of that, blink_mode is assigned twice in the same statement, which means the result is actually indeterminate.
Not really, but only because this is a particular special case. Stating the exact nature of the special case would, however, take more space than I have in this margin.
-
Perhaps you're balking at the word "indeterminate" when the terminology is "undefined", but this isn't a special case and the result cannot be determined in advance simply by looking at the code and making assumptions: http://c-faq.com/expr/ieqiplusplus.html
No, no, he's right. In fact, I myself happen to have a practical attack on AES and RSA, the description of which is too big to fit in this margin. :p
[url=http://www.gap-system.org/~history/Quotations/Fermat.html]Cuius rei demonstrationem mirabilem sane detexi hanc marginis exiguitas non caperet[/url]
-
@Carnildo said:
blink_mode = (++blink_mode) & 1;
I particularly like the brackets. Y'know, just in case the pre-increment operator randomly decides to post-increment for a change.
-
Ah, if you needed to toggle and test, you could do this anyways?
[code]if(blink_mode^=1)[/code]
Or, with 16X CPU architecture, this?
[code]F TGL AX ?0. BRZ {.[/code]
Or, with GameBoy, this?
[code]XOR $01 JR Z,[/code]
-
I want to have an update statement like:
update tblMydate set fieldx=fieldx+1 where code=12
But then for a boolean value:
So, if the current boolean value is true, I want to set it to false and vice versa, something like
update tblMydate set booleanx=not booleanx where code=12
How can I achieve this?edit: killed erroneous h2 — mod
-
@mamun01 said:
How can I achieve this?
Simple, create the follwing table:
CREATE TABLE booleanInv(
value BOOL PRIMARY_KEY,
inverted BOOL UNIQUE
)
INSERT INTO booleanInv(true,false);
INSERT INTO booleanInv(false, true);
now you can use the following query:
UPDATE tblMydate SET booleanx = (SELECT inverted FROM booleanInv WHERE value = booleanx) WHERE code = 12
-
@ThePants999 said:
I don't think that's what they're for, I think they're there to prevent the association going wrong. Without them, the code might be misinterpreted as@Carnildo said:
blink_mode = (++blink_mode) & 1;
I particularly like the brackets. Y'know, just in case the pre-increment operator randomly decides to post-increment for a change.
@Carnildo said:blink_mode = ++(blink_mode & 1);
and you could end up accidentally incrementing the value of zero or one!
-
@gms8994 said:
Unless you're using a system where NULL isn't 0 or 1, and a ! wouldn't normalize it either way...
Please send some of whatever you were on when you learned C, kthxbye.