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 executes 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);

Bitwise Operators

Bitwise operators allow you to test and set individual bits. The operands 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; 
out_int("perms after clear = ", perms); // 0x01

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

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