1.2.2 Operators

Operators in Origin C support the same arithmetic, logical, comparison, and bitwise operators as ANSI C. The sections below list the four operator types and show usage.

Arithmetic Operators

Operator Definition Example
*
multiplication 10 * 3 -> 30
/
division 6 / 2 -> 3
%
modulus (remainder) 11 % 2 -> 1
+
addition 5 + 4 -> 9
-
subtraction 9 - 4 -> 5
^
exponentiation (power)
See note below.
10 ^ 3 -> 1000 (Origin C default)

Note. By default, Origin C treats the caret (^) as the —the exponentiation (power) operator—to match LabTalk. In standard ANSI C, ^ is the bitwise XOR operator. To use ^ as XOR in Origin C, add #pragma xor before your code (e.g., #pragma xor(push, FALSE)#pragma xor(pop)).

out_int("10 raised to the 3rd is ", 10^3); // default: ^ is exponent in Origin C

#pragma xor(push, FALSE)                   // interpret ^ as XOR
out_int("10 XOR 3 is ", 10^3);
#pragma xor(pop)                           // restore default

// Portable exponentiation that never needs pragma:
out_double("pow(10,3) is ", pow(10,3));

Dividing an integer by another integer yields an integer result by default. Use the pragma below so the compiler treats numeric literals as double.

int a = 3, b = 2;

out_double("a/b           -> ", a/b);           // 1 (integer division)
out_double("3/2           -> ", 3/2);           // 1 (integer division)
out_double("3/2.0         -> ", 3/2.0);         // 1.5 (double literal)
out_double("(double)3/2   -> ", (double)3/2);   // 1.5 (explicit cast)

// Treat numeric literals as double so 3/2 becomes 1.5:
#pragma numlittype(push, TRUE)
out_double("3/2 with numlittype -> ", 3/2);     // 1.5

// Variables still follow normal promotions; these now become double
out_double("3/b with numlittype  -> ", 3/b);    // 1.5
out_double("a/2 with numlittype  -> ", a/2);    // 1.5
#pragma numlittype(pop) // restore default

The calculates the remainder of the left operand divided by the right operand. This operator can only be applied to integral operands.

out_int("The remainder of 11 divided by 2 is ", 11 % 2);

A common pattern is to test odd/even:

int n = 27;
out_str(n % 2 ? "27 is odd" : "27 is even");

Comparison Operators

Comparison operators evaluate to true or false with true yielding 1 and false yielding 0.

Operator Definition Example
>
greater than 5 > 4 -> 1
>=
greater than or equal to 5 >= 5 -> 1
<
less than 3 < 2 -> 0
<=
less than or equal to 2 <= 2 -> 1
==
equal to 7 == 7 -> 1
!=
not equal to 7 != 8 -> 1
if( aa >= 0 )
    out_str("aa is greater than or equal to zero");

if( 12 == aa )
    out_str("aa is equal to twelve");
	
if( aa < 99 )
    out_str("aa is less than 99");

Logical Operators

Logical operators evaluate to true or false with true yielding 1 and false yielding 0. The operands are evaluated from left to right. Evaluation stops when the entire expression can be determined (short-circuit).

Operator Definition Example
!
NOT !0 -> 1
&&
AND 1 && 0 -> 0
||
OR 0 || 1 -> 1


Consider the following two examples:

expr1A && expr2
expr1B || expr2

expr2 will not be evaluated if expr1A evaluates to false or expr1B evaluates to true. Ordering can prevent errors and improve efficiency. For example, guard against divide-by-zero:

int denom = 0, num = 10;
// Safe: right side never executed because denom == 0 makes whole && false
if ( denom != 0 && (num / denom) > 2 )
    out_str("greater than 2");
// Reversing the order could evaluate num/denom first and fail.

Another classic short-circuit guard uses a NULL check:

if( NULL != ptr && ptr->dataValue < upperLimit )
    process_data(ptr);

In the above example the entire if expression will evaluate to false if ptr is equal to NULL. If ptr is NULL then it is very important that the dataValue not be compared to upperLimit because reading the member from a NULL pointer can cause an application to end abruptly.

Bitwise Operators

Bitwise operators allow you to test and set individual bits. The operator treats the operands as an ordered array of bits. The operands of a bitwise operator must be of integral type.

Operator Definition Example
~
bitwise complement (invert bits) ~5 -> 250 (00000101 → 11111010, 8-bit)
<<
shift left 1 << 3 -> 8 (00000001 → 00001000)
>>
shift right 8 >> 2 -> 2 (00001000 → 00000010)
&
bitwise AND 6 & 3 -> 2 (00000110 & 00000011 = 00000010)
^
bitwise exclusive OR (XOR)
See note below.
5 ^ 3 -> 6 (00000101 ^ 00000011 = 00000110; requires #pragma xor)
|
bitwise inclusive OR 5 | 2 -> 7 (00000101 | 00000010 = 00000111)


Note. By default, Origin C treats ^ as exponentiation (power). Use #pragma xor to interpret ^ as bitwise XOR instead:

out_int("10 raised to the 3rd is ", 10^3);
#pragma xor(push, FALSE)
out_int("10 XOR 3 is ", 10^3);
#pragma xor(pop)

Common bit-mask patterns:

// Bit flags
const int FLAG_READ  = 0x01;  // 0001
const int FLAG_WRITE = 0x02;  // 0010
const int FLAG_EXEC  = 0x04;  // 0100

int perms = 0;
perms |= FLAG_READ;                 // set
perms |= FLAG_WRITE;                // set
out_int("perms after set    = ", perms); // 0x03

perms &= ~FLAG_WRITE;               // clear
out_int("perms after clear  = ", perms); // 0x01

perms ^= FLAG_EXEC;                 // toggle
out_int("perms after toggle = ", perms); // 0x05

out_str( (perms & FLAG_READ) ? "READ on" : "READ off" ); // test