This question already has an answer here:
-
Why can't we use bitwise operators on float & double data types
2 answers
These are two simple samples in C++ written on Dev-cpp C++ 5.4.2:
float a, b, c;
if (a | b & a | c)
printf("x = %.2f\tF = %.0f\n", x, F);
else
printf("x = %.2f\tF = %.2f\n", x, F);
and this code :
float a, b, c;
if (a || b && a || c)
printf("x = %.2f\tF = %.0f\n", x, F);
else
printf("x = %.2f\tF = %.2f\n", x, F);
Can somebody tell my difference between ||
> |
and &
> &&
. The second code works , but first does not.
And compiler gives an error message :
[Error] invalid operands of types 'float' and 'float' to binary 'operator&'.
The operators |
, &
, and ~
act on individual bits in parallel. They can be used only on integer types. a | b
does an independent OR operation of each bit of a
with the corresponding bit of b
to generate that bit of the result.
The operators ||
, &&
, and !
act on each entire operand as a single true
/false
value. Any data type can be used that implicitly converts to bool
. Many data types, including float
implicitly convert to bool with an implied !=0
operation.
||
and &&
also "short circuit". That means whenever the value of the result can be determined by just the first operand, the second is not evaluated. Example:
ptr && (*ptr==7)
If ptr
is zero, the result is false without any risk of seg faulting by dereferencing zero.
You could contrast that with (int)ptr & (*ptr)
. Ignoring the fact that this would be a bizarre operation to even want, if (int)ptr
were zero, the entire result would be zero, so a human might think you don't need the second operand in that case. But the program will likely compute both anyway.
You seems be confused with the symbols of the operators. Theses symbols are actually split in two different categories, which are bit-wise operators and logical operators. Although they use the same symbols, you should regard them as different operators. The truth tables for both categories are similar, but the meanings are different. Maybe that's why people use the similar symbols for the operators.
bit-wise operators
~ // NOT
& // AND
| // OR
^ // XOR
The bit-wise operators will regard all its operands as binary numerals and act according to the bit-wise truth tables on every bit of the operands.
Bit-wise Truth Table
x y x&y x|y x^y
0 0 0 0 0
1 0 0 1 1
0 1 0 1 1
1 1 1 1 0
x ~x
0 1
1 0
logical operators
! // Logical NOT (negation)
&& // Logical AND (conjunction)
|| // Logical OR (disjunction)
The logical operator will regard all its operands as bools and act according the operator truth tables. Any number that is not equal to 0
will be true
, else will be false
.
Logical Truth Table
x y x&&y x||y
F F F F
T F F T
F T F T
T T T T
x !x
F T
T F
For example:
int a = 10; // a = 0000 .... 0000 1010 <-- a 32 bits integer
// a is not zero -> true
int b = 7; // b = 0000 .... 0000 0111 <-- a 32 bits integer
// b is not zero -> true
Then for bit-wise operator:
assert(a & b == 2); // 2 = 0000 .... 0000 0010 <-- every bit will & separately
For logic operator:
assert(a && b == true); // true && true -> true
The bitwise operators, which are |
(OR), &
(AND), ^
(XOR), and ~
(complement) do what you expect them to do: they perform the aforementioned operations on bits.
And regarding your compilation issue, there are no bitwise operations for floating point numbers.
The logical operators, which are ||
(OR), &&
(AND), and !
(NOT) only know the values true
and false
.
An expression is true
if its value is not 0
. It is false
if its value equals 0
.
The logical operators do this operation first. Then they perform their corresponding operation:
||
: true
if at least one the operands is true
&&
: true
if both operands are true
!
: true
if the operand is false
Note that all logical operators are short-circuit operators.
Bitwise operation is not supported for floating points
Alternatively if you really need to check, you can cast before you use them (highly discouraged),
Check here how to convert a float into integrals, https://www.cs.tut.fi/~jkorpela/round.html