KAHIBARO
Discord Login Register

2.3 Operators

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:

OperationOperatorExampleResult (if a = 7, b = 3)
Addition+a + b10
Subtraction-a - b4
Multiplication*a * b21
Division/a / b2 (integer division)
Remainder%a % b1

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:

OperatorEquivalent toDescription
a += ba = a + bAdd and assign
a -= ba = a - bSubtract and assign
a *= ba = a * bMultiply and assign
a /= ba = a / bDivide and assign
a %= ba = a % bRemainder 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:

OperatorMeaningTypical use
++iPre-incrementIncrease then use
i++Post-incrementUse then increase
--iPre-decrementDecrease then use
i--Post-decrementUse 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:

OperationOperatorExampleMeaning
Equal to==a == btrue if a equals b
Not equal to!=a != btrue if a is not b
Greater than>a > btrue if a greater than b
Less than<a < btrue if a less than b
Greater than or equal>=a >= btrue if a at least b
Less than or equal<=a <= btrue 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:

OperationOperatorExampleMeaning
Logical AND&&a && btrue if both a and b are true
Logical OR`\\``a \\b`true if at least one of a or b is true
Logical NOT!!atrue 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

Comments

Please login to add a comment.

Don't have an account? Register now!