I am trying to adapt some code I found online for calculating a parabolic SAR (https://github.com/TulipCharts/tulipindicators/blob/master/indicators/psar.c). Being C, it runs fine.
But in C , I get a green ziggy line under !lng
saying:
using '!' logical when bitwise '~' was probably intended
If I change from lng = !lng;
to lng = ~lng;
, it computes the incorrect output. So I have left it as the original code.
But I was wondering, how can I fix this/update it to C , so I don't have the "error" message? Also, what is the difference in C between !
and ~
? Why does it cause a difference in the outputs?
if ((lng && low[i] < sar) || (!lng && high[i] > sar)) {
accel = accel_step;
sar = extreme;
lng = !lng;
if (!lng) extreme = low[i];
else extreme = high[i];
}
CodePudding user response:
A couple of things to clear up confusion:
If you change the line lng = !lng
to be lng = ~lng
, here's what happens. If the value of lng
is 0, the bitwise complement will give you 0xffffffff
, assuming a 32-bit integer. If this value is used in a boolean check, it will evaluate to "true" because it's non-zero. If the value of lng
is 1, the bitwise complement will give you 0xfffffffe
, which will also evaluate to "true" in a boolean check, again because it's nonzero. This is why it breaks your code.
If you want to compile with a C compiler, you can change the type of lng
to bool
as others have suggested. If you're planning to stick with C, you can also use bool
, but you'll need to first #include <stdbool.h>
, and make sure you're compiling with a C version greater than or equal to C99.
Another way to fix this is just to use an xor with 1 whenever you want to invert the value. So instead of lng = !lng
(which the compiler expands logically to lng = (lng != 0)
as @BenVoigt pointed out), you can do lng ^= 1
. This allows you to continue treating lng
as an integer numeric value (i.e. not a bool in the strictest sense) and thereby get rid of the warning without changing much else.
CodePudding user response:
Since we now know that the green ziggy in question is displayed in VS 2022, it's possible to formulate an answer.
I think this warning is just noise personally - that code is perfectly legitimate as it was - but fortunately there's a way to turn it off. Just change:
Options -> Text Editor -> C/C -> Code Style -> Linter -> Logical/Bitwise Mismatch
to None and you're done.