if statements with integers

  • Thread starter northsolomonsea
  • Start date
N

northsolomonsea

Hi,
I apologize if this is trivial, been searching around but can't get
find a good explanation.

I often see statements like

if (val&SOME_ERROR_CODE) { ...
if (SOMECODE_SOMEOTHERCODE) {

etc.

where the macros are integer values, usually "bit" values 8, 16, 32
etc.
Can someone explain to me when they are true and when they are false?
what is the logic behind it? (a pointer to a webpage explaining would
also do fine as well).
thanks very much. R
 
N

northsolomonsea

It is trivial, but don't apologise.

The operator& clears all bits except the ones set in both operands.  So,
if one of the operands is a single bit value, the operation results in 0
if the corresponding bit is not set in the other operands, or non-zero
if the corresponding bit *is* set.  The conversion of an integral
expression to 'bool' yields 'false' if the integral expression is 0, and
'true' if the expression is not zero.  Thus, the 'if (blah & some_bit)'
checks if the specific bit is set or cleared.

The second example you gave is a bit obscure.  What is the meaning of
'SOMECODE_SOMEOTHERCODE'?  Is that a single value?  Then it's just the
expression that gets converted to 'bool' before being tested by the
'if', a non-zero value yields 'true', the zero yields 'false'.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask- Hide quoted text -

- Show quoted text -

Victor,
Thanks very much for your reply!

So if I'm correct then any value other than zero will evaluate to TRUE
in an if statement? Does it mean that if any bit is equal to 1 in an
integer it will become TRUE but if no bits are equal to 1 in the
integer it will be a FALSE?

The second statetment contained a typo, I'm sorry, it should have
read: SOMECODE||SOMEOTHERCODE but I think I understand that one from
your explanation for the "&" case.

thanks, R
 
N

northsolomonsea

[..]
So if I'm correct then any value other than zero will evaluate to TRUE
in an if statement? Does it mean that if any bit is equal to 1 in an
integer it will become TRUE but if no bits are equal to 1 in the
integer it will be a FALSE?

Well, yes.  We don't use uppercase notation for bool literals, so, it's
'true' and 'false' instead of 'TRUE' and 'FALSE', though. :)
The second statetment contained a typo, I'm sorry, it should have
read: SOMECODE||SOMEOTHERCODE but I think I understand that one from
your explanation for the "&" case.

There is a difference between an integral expression with the '&' and
the logical expression with the '||', but I will take your word that you
understand it.

V

Thanks very much Victor (also for taking my word ;))
 
J

Juha Nieminen

So if I'm correct then any value other than zero will evaluate to TRUE
in an if statement?

No, it evaluates to 'true'. There's no such keyword as 'TRUE' in C++.
This is not just nitpicking. ('true' is standard, 'TRUE' isn't, which
makes a big difference.)
Does it mean that if any bit is equal to 1 in an
integer it will become TRUE but if no bits are equal to 1 in the
integer it will be a FALSE?

If any bit in the integer is 1 it means that the value of that integer
is not zero. Thus when casted to bool, it will be converted to true.
 
R

Rolf Magnus

So if I'm correct then any value other than zero will evaluate to TRUE
in an if statement?

It's not specific to if statements, but to converting an integer to bool.
Since the if statement expects a bool, this conversion is done implictly.
But wherever you convert an integer to bool, this rule applies.
 
J

James Kanze

On Oct 9, 2:50 pm, Victor Bazarov <[email protected]> wrote:
So if I'm correct then any value other than zero will evaluate
to TRUE in an if statement? Does it mean that if any bit is
equal to 1 in an integer it will become TRUE but if no bits
are equal to 1 in the integer it will be a FALSE?

For historical reasons, there is an implicit conversion of all
arithmetic types to bool: if the value is equal zero (or the the
null pointer, for pointer types), it is converted to false;
otherwise to true.

This is really a legacy feature, and should generally be avoided
in modern code. (There is a tendancy to exploit them in
expressions using & and | because the precedence of these
operators is wrong. Thus:
if ( a & b != 0 )
does NOT do what you might expect; you generally need:
if ( (a & b) != 0 )
..)
The second statetment contained a typo, I'm sorry, it should
have read: SOMECODE||SOMEOTHERCODE but I think I understand
that one from your explanation for the "&" case.

Attention: && and || are very different from & and |. The
first are logical, connective and and or: the left operand is
converted to bool (if it isn't bool already); the right operand
is only evaluated if necessary. So things like:
if ( p != NULL && p->someValue != 0 )...
are guaranteed to not result in a null pointer access. The &
and | operators, on the other hand, are bitwise operators on
integral types; integral promotion is applied to both operands
(so an operand of type bool is converted to int), then the usual
arithmetic conversions are applied, and the resulting values are
or'ed or and'ed bit by bit. Note that this can (at least
theoretically) result in some surprises if negative values are
involved, since the representation of negative values varies (or
can vary); for this reason, some programmer (like myself) only
use them on unsigned integral types.
 
J

Juha Nieminen

James said:
Attention: && and || are very different from & and |. The
first are logical, connective and and or: the left operand is
converted to bool (if it isn't bool already); the right operand
is only evaluated if necessary. So things like:
if ( p != NULL && p->someValue != 0 )...
are guaranteed to not result in a null pointer access.

There's also another difference, because && and & do completely
different things. For example:

int i = 1, j = 2;
if(i & j) // this evaluates to false
if(i && j) // this evaluates to true

The & operator takes two integral values and performs a bitwise-and of
these values, ie. 1 and 2 in this case. Since those values do not share
any common bits, the result of their bitwise-and is zero, and zero is
converted to false.

The && operator, on the other hand, takes two boolean values. Thus
both values 1 and 2 are *first* converted to boolean, ie. true (because
both are distinct from zero), and then a logical-and of these two true
values is evaluated, which results in true.

It's very rarely a good idea to perform a boolean comparison of two
variables with the bitwise-and operator (or the bitwise-or operator).
Bitwise-and is usually used when applying bitmasks to some value. The
only common idiom where bitwise-and is used for boolean comparison is
with a variable and a constant, which basically expresses "is this bit
set in this variable?".
There are basically no situations where you would want to make a
boolean comparison using the bitwise-or operator.
 
M

Matthias Buelow

Juha said:
If any bit in the integer is 1 it means that the value of that integer
is not zero.

This isn't necessarily true, depending on the representation of integers
on a particular machine.
 
J

James Kanze

There's also another difference, because && and & do
completely different things.

That's what I said in the part you cut. About all they have in
common, in fact, is that they are both operators.
 
J

Juha Nieminen

Matthias said:
This isn't necessarily true, depending on the representation of integers
on a particular machine.

I thought the standard guaranteed complement-of-2 representation.
That's eg. why "a >> 1" divides a by 2.
 
R

Rolf Magnus

Juha said:
I thought the standard guaranteed complement-of-2 representation.

No. It could also be 1s-complement or sign/magnitude representation, and
both of those have two zero values, one of which obviously is not all bits
zero.
That's eg. why "a >> 1" divides a by 2.

... for positive numbers.
 
J

James Kanze

No. It could also be 1s-complement or sign/magnitude
representation, and both of those have two zero values, one of
which obviously is not all bits zero.

Note that there are still machines with both of these
representations being built and sold today.
.. for positive numbers.

Yes. The results of shifting a negative value right are
implementation defined.

I'm pretty sure, too, that the standard allows negative zero's
to propagate in an expression. So on a Unisys 2200, something
like (0x800000000 & (expressionEvaluatingToZero)) is not
guaranteed to be 0.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,459
Latest member
Vida00R129

Latest Threads

Top