What Is the Type of the Logical Operators

What is the type of the logical operators?

If you "cmd-click" on the word "Swift" in the statement

import Swift

in Xcode and search for || then you'll find that it is declared as

func ||<T : BooleanType>(lhs: T, rhs: @autoclosure () -> Bool) -> Bool

The reason is the "short-circuiting" behaviour of the || operator: If the first
operand is true, then the second operand must not be evaluated at all.

So you have to declare the parameter as

combine: (Bool, @autoclosure () -> Bool) -> Bool

Example:

func combineWith(a : Bool, b : Bool, combine: (Bool, @autoclosure () -> Bool) -> Bool) -> Bool {
return combine(a, b)
}

let result = combineWith(false, true, ||)
println(result)

Note: I tested this with Xcode 6.1.1. The syntax for autoclosure
parameters changed in Swift 1.2 (Xcode 6.3) and I haven't been able yet
to translate the above code for Swift 1.2 (see also Rob's comments
below).

The only thing that I can offer at the moment are extremely ugly
workarounds. You could wrap || into a closure that does not have
autoclosure parameters:

func combineWith(a : Bool, b : Bool, combine: (Bool, () -> Bool) -> Bool) -> Bool {
return combine(a, { b })
}

let result = combineWith(false, true, { $0 || $1() } )

Or you go without the short-circuiting behaviour:

func combineWith(a : Bool, b : Bool, combine: (Bool, Bool) -> Bool) -> Bool {
return combine(a, b)
}

let result = combineWith(false, true, { $0 || $1 } )

Logical Operators in C

The && is a logical AND (as opposed to &, which is a bitwise AND). It cares only that its operands as zero/non-zero values. Zeros are considered false, while non-zeros are treated as true.

In your case, both operands are non-zero, hence they are treated as true, resulting in a result that is true as well. C represents true as 1, explaining the overall result of your operation.

If you change the operation to &, you would get a bitwise operation. 0x65 & 0x55 will give you a result of 0x45.

complex logical operation

Yes:

A and B or C and D

In most programming languages, and is taken to have higher precedence than or (this stems from the equivalence of and and or to * and +, respectively).

Of course, if your original expression had been:

(A or B) and (C or D)

you couldn't simply remove the parentheses. In this instance, you'd have to "multiply out" the factors:

A and C or B and C or A and D or B and D

Logical operators for Boolean indexing in Pandas

When you say

(a['x']==1) and (a['y']==10)

You are implicitly asking Python to convert (a['x']==1) and (a['y']==10) to Boolean values.

NumPy arrays (of length greater than 1) and Pandas objects such as Series do not have a Boolean value -- in other words, they raise

ValueError: The truth value of an array is ambiguous. Use a.empty, a.any() or a.all().

when used as a Boolean value. That's because it's unclear when it should be True or False. Some users might assume they are True if they have non-zero length, like a Python list. Others might desire for it to be True only if all its elements are True. Others might want it to be True if any of its elements are True.

Because there are so many conflicting expectations, the designers of NumPy and Pandas refuse to guess, and instead raise a ValueError.

Instead, you must be explicit, by calling the empty(), all() or any() method to indicate which behavior you desire.

In this case, however, it looks like you do not want Boolean evaluation, you want element-wise logical-and. That is what the & binary operator performs:

(a['x']==1) & (a['y']==10)

returns a boolean array.


By the way, as alexpmil notes,
the parentheses are mandatory since & has a higher operator precedence than ==.

Without the parentheses, a['x']==1 & a['y']==10 would be evaluated as a['x'] == (1 & a['y']) == 10 which would in turn be equivalent to the chained comparison (a['x'] == (1 & a['y'])) and ((1 & a['y']) == 10). That is an expression of the form Series and Series.
The use of and with two Series would again trigger the same ValueError as above. That's why the parentheses are mandatory.

Return types of operator == in C


Return types of operator == in C

... The result has type int. ... C11dr Equality operators §6.5.9 3

What is the return type of any operator ?

Sometimes it depend on the operator and the operands

a*b --> result type could be `int`, `double`, etc.

Others, it is fixed.

a==b --> result type is `int`.

How to determine it?

  1. By code analysis - you or a static analyzer looks at the code.

  2. At run time, use _Generic()

The following handles many situations.

#define typenameX(X) _Generic((X), \
_Bool: "_Bool", \
signed char: "signed char", \
char: "char", \
unsigned char: "unsigned char", \
short: "short", \
unsigned short: "unsigned short", \
int: "int", \
unsigned: "unsigned", \
long: "long", \
unsigned long: "unsigned long", \
long long: "long long", \
unsigned long long: "unsigned long long", \
float: "float", \
double: "double", \
long double: "long double", \
_Complex float: "_Complex float", \
_Complex double: "_Complex double", \
_Complex long double: "_Complex long double", \
void *: "void *", \
char *: "char *", \
const char *: "const char *", \
default: "other" \
)

int main(void) {
double a = 2.0;
puts(typenameX(a));
puts(typenameX(a==4.0));
short b;
puts(typenameX(b));
puts(typenameX(b*1));
puts(typenameX(sizeof(b)));
double cmd;
puts(typenameX(cmd <= 1));
}

Output

double
int
short
int
unsigned long
int

Is it platform dependent ?

With cmd <= 1, the return type in C is int - "platform independent".

The result type of ((int)i) * 123456 is "platform dependent". It could be int or long for example.

can you point me to some documentation regarding operator return type ?

In the case of if((bool_t)(cmd <= 1)){}, the result type of cmd <= 1 is int. C11 §6.5.8 6. The bool_t is not needed when compiling in C. Since the result type may differ in other languages (or with a non-compliant C compiler), code that needs to compile in more than one language may benefit by the cast.

The best document regarding operator return type is the (latest) C spec.


The concerns about "required to typecast the parameters of the if keyword" comes into play in arcane situations. The result of a compare in C is not one of them.

C well defines the result of if(expression) to be "if the expression compares unequal to 0.". C11dr §6.8.4.1 2

A non-compliant compiler may convert floating-point or a wide integer to an int first and then test against zero. if((bool_t)x) fixes that.

unsigned long long w = 0x800000000000u;
if (w) {

double x = 4294967296.0; // 0x1 0000 0000
if (x) {

double y = 0.123;
if (y) {

Handling of NaN is problematic. OTOH, C does not well define how NaN compares to 0. IEEE 758 does well define it and many C implementations follow that. I do not see casting to (bool_t) helps in this case as it is equally lose concerning NaN.

double z = 0.0/0.0; // z is NaN;
if (z) {

if (!z) {

In early C++, there was no boolean either. A user defined object, (but not double, float, pointers), was converted to int for the if(). An arithmetic class (e.g. effecting a 256 integer) would have trouble should a non-zero value convert to int 0. Using !! solved that.

myint256 a = foo();
if (!!a) {

Note: If a compiler does not have a true boolean type, then (bool_t) being maybe some integer type, will certainly foul code, much like above.

result of logical operation

Though the symbol used for it looks similar, this is not a boolean operation,

it's a bitwise operation and returns an int, not a boolean. See also:

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html

Note that you used & (bitwise AND) and not && (logical AND).

Are the &, |, ^ bitwise operators or logical operators?

The Java operators &, | and ^ are EITHER bitwise operators OR logical operators ... depending on the types of the operands. If the operands are integers, the operators are bitwise. If they are booleans, then the operators are logical.

And this is not just me saying this. The JLS describes these operators this way too; see JLS 15.22.

(This is just like + meaning EITHER addition OR string concatenation ... depending on the types of the operands. Or just like a "rose" meaning either a flower or a shower attachment. Or "cat" meaning either a furry animal or a UNIX command. Words mean different things in different contexts. And this is true for the symbols used in programming languages too.)


There are already logical operators &&, ||, why use &, |, ^?

In the case of the first two, it is because the operators have different semantics with regards to when / whether the operands get evaluated. The two different semantics are needed in different situations; e.g.

    boolean res = str != null && str.isEmpty();

versus

    boolean res = foo() & bar();  // ... if I >>need<< to call both methods.

The ^ operator has no short-circuit equivalent because it simply doesn't make sense to have one.

The written versions of the logical operators

They originated in C in the header <iso646.h>. At the time there were keyboards that couldn't type the required symbols for && (for example), so the header contained #define's that would assist them in doing so, by (in our example) defining and to be &&. Of course, as time went by this became less used.

In C++, they became what are known as alternate tokens. You do not need to include anything to use these tokens in a compliant compiler (as such, the C++-ified version of the C header, <ciso646>, is blank). Alternate tokens are just like regular tokens, except for spelling. So during parsing and is exactly the same as &&, it's just a different way of spelling the same thing.

As for their use: because they are rarely used, using them is often more surprising and confusing than it is helpful. I'm sure if it were normal, they would be much easier to read, but people are so used to && and || anything else just gets distracting.

EDIT: I have seen a very slight increase in their usage since I posted this, however. I still avoid them.

What is the difference between logical and conditional AND, OR in C#?

I prefer to think of it as "bitwise vs. conditional" rather than "logical vs conditional" since the general concept of "logical" applies in both cases.

x & y    // bitwise AND, 0101 & 0011 = 0001
x | y // bitwise OR, 0101 | 0011 = 0111

x && y // true if both x and y are true
x || y // true if either x or y are true

Edit

By popular demand, I should also mention that the arguments are evaluated differently. In the conditional version, if the result of the entire operation can be determined by the first argument, the second argument is not evaluated. This is called short-circuit evaluation. Bitwise operations have to evaluate both sides in order to compute the final value.

For example:

x.foo() && y.bar()

This will only call y.bar() if x.foo() evaluates to true. Conversely,

x.foo() || y.bar()

will only call y.bar() if x.foo() evaluates to false.

Logical operators from Array[object..]

You just need to run reduce operator and return a new operator object that will have the logic of previous operator and value or current computation.