2.3 Operators
Table of Contents
Arithmetic operators
In C++ you use arithmetic operators to perform numerical calculations on integers and floating point numbers. ROOT uses these operators everywhere, for example when computing new variables before filling a histogram or when evaluating expressions in the interactive shell.
The basic arithmetic operators are:
| Operation | Operator | Example | Result (if a = 7, b = 3) |
|---|---|---|---|
| Addition | + | a + b | 10 |
| Subtraction | - | a - b | 4 |
| Multiplication | * | a * b | 21 |
| Division | / | a / b | 2 (integer division) |
| Remainder | % | a % b | 1 |
The division operator / behaves differently for integers and floating point types. If both operands are integers, the result is integer division and any fractional part is discarded. If at least one operand is floating point, the result is floating point division.
If both operands of / are integers, the result is integer division and the fractional part is discarded. To get a floating point result, make at least one operand float or double, for example a / 3.0 or a / double(b).
The remainder operator % only works with integer types. It gives you the remainder after integer division, which is often used in loops, for example to select every tenth event.
C++ also provides compound assignment operators that combine an operation with assignment. These are very common in analysis code because they make accumulation and updates concise:
| Operator | Equivalent to | Description |
|---|---|---|
a += b | a = a + b | Add and assign |
a -= b | a = a - b | Subtract and assign |
a *= b | a = a * b | Multiply and assign |
a /= b | a = a / b | Divide and assign |
a %= b | a = a % b | Remainder and assign (integers) |
In event loops you will often see sum += value; to accumulate totals or count += 1; to count events that pass a selection.
There are also increment and decrement operators that change a variable by one:
| Operator | Meaning | Typical use |
|---|---|---|
++i | Pre-increment | Increase then use |
i++ | Post-increment | Use then increase |
--i | Pre-decrement | Decrease then use |
i-- | Post-decrement | Use then decrease |
In most ROOT analysis code you will use i++ in for loops, for example when looping over histogram bins or TTree entries.
Comparison operators
Comparison operators test relationships between values. They are fundamental for selection cuts, if statements, and loops in ROOT macros. The result of a comparison is a boolean value, true or false.
The main comparison operators are:
| Operation | Operator | Example | Meaning |
|---|---|---|---|
| Equal to | == | a == b | true if a equals b |
| Not equal to | != | a != b | true if a is not b |
| Greater than | > | a > b | true if a greater than b |
| Less than | < | a < b | true if a less than b |
| Greater than or equal | >= | a >= b | true if a at least b |
| Less than or equal | <= | a <= b | true if a at most b |
The equality test uses ==. The single equal sign = is assignment. Confusing == with = changes a variable instead of comparing it and can completely change the logic of your selection.
When you write selection cuts for TTrees or in if statements, you combine arithmetic expressions with comparison operators. A typical example in a ROOT macro is a cut like
if (energy > 1.0 && energy < 3.0) { / fill histogram / }
Here > and < produce boolean values that are then combined with logical operators, which are described in the next section.
For floating point values, exact equality comparisons like x == 0.1 can be unreliable because of rounding. A common pattern in numerical code is to test if values are close within a small tolerance, for example
fabs(x - y) < 1e-6
instead of x == y. This becomes important when comparing calculated quantities in analysis code.
Logical operators
Logical operators combine or invert boolean expressions. They allow you to build complex conditions from simpler comparisons, which is central for event selection in ROOT.
The basic logical operators in C++ are:
| Operation | Operator | Example | Meaning | ||||
|---|---|---|---|---|---|---|---|
| Logical AND | && | a && b | true if both a and b are true | ||||
| Logical OR | `\ | \ | ` | `a \ | \ | b` | true if at least one of a or b is true |
| Logical NOT | ! | !a | true if a is false |
In conditions involving event variables, && corresponds to applying two cuts at the same time and \|\| corresponds to accepting events that pass either of two cuts.
For example, in a ROOT macro:
if (energy > 1.0 && time < 50.0) { / selected events / }
selects events where both conditions are satisfied. On the other hand,
if (energy < 0.5 || energy > 5.0) { / outside signal region / }
selects events with energy either below 0.5 or above 5.0.
The logical NOT operator ! inverts a condition. It is often used to explicitly reject events:
if (!goodEvent) continue;
This skips processing for events that do not satisfy goodEvent. You can also negate comparisons, for example !(x < 0) is equivalent to x >= 0.
C++ uses short circuit evaluation for && and \|\|. For a && b, if a is false, b is never evaluated because the result cannot be true. For a \|\| b, if a is true, b is not evaluated. This can be useful when writing conditions that first check simple or cheap tests, then more expensive ones, for example:
if (energy > 0 && passBasicQuality && complexCheck()) { ... }
so that complexCheck() is called only when the earlier conditions are already satisfied.
In many ROOT interfaces, such as TTree::Draw, logical operators appear inside selection strings. The syntax is the same C++ syntax you use in macros, so understanding &&, \|\|, and ! in simple code will directly carry over to more advanced ROOT analyses.
Views: 11
KAHIBARO