# Operators

## Mathematical Operators

The following mathematical operators are used in KoLmafia:

+ | Addition | Performs addition and string concatenation |

- | Subtraction | Performs subtraction |

* | Multiplication | Performs multiplication |

/ | Division | Performs division |

% | Modulo | Returns the remainder after division |

** | Exponent | Performs exponentiation |

Note that, with the exception of using "+" for string concatenation, these operators can only be used on int or float datatypes.

## Bitwise Operators

The following mathematical operators are used for operating on the bits of integers. The logical operators (&, |, ^) work either with booleans or integers while the others operate upon integers only. If the operands are booleans, then result will also be a boolean.

& | and | a & b |

| | or | a | b |

^ | XOR | a ^ b |

~ | not | ~a |

<< | left shift | a << b |

>> | right shift | a >> b |

&= | and | a &= b --> a = a & b |

|= | or | a |= b --> a = a | b |

>>> | unsigned right shift | a >>> b |

## Assignment Operators

The following assignment operators are used in KoLmafia (let a = left operand, b = right operand):

= | a = b |

+= | a = a + b |

-= | a = a - b |

*= | a = a * b |

/= | a = a / b |

%= | a = a % b |

**= | a = a ** b |

^= | a = a ^ b |

>>= | a = a >> b |

>>>= | a = a >>> b |

Of these, only += and = are usable for strings. See Mathematical Operators for information regarding the basic Mathematical Operators.

## Relational Operators

To follow these examples, a basic understanding of the concepts found on Control Structures would be helpful.

In order to create more complex if statements, we need to understand the basic relational operators:

== | equal to |

!= | not equal to |

< | less than |

> | greater than |

<= | less than or equal to |

>= | greater than or equal to |

≈ | approximately equal to |

Note that you cannot mix most datatypes within a comparison or KoLmafia will abort with an error, with the exception of mixing types int and float, where KoLmafia will do a transparent type conversion behind-the-scenes. If you need to compare different datatypes, use one or more of the Datatype Conversion functions.

```
if ( true == true )
{
print( "This line DOES get printed." );
}
if ( true == false )
{
print( "This line does NOT get printed." );
}
if ( 1 == 1.0 )
{
print( "This line DOES get printed." );
}
if ( 1 == 2 )
{
print( "This line does NOT get printed." );
}
if ( "Hello" == "hello" )
{
print( "This line does NOT get printed." );
}
```

As of r16180, the equality (`==`

) and inequality (`!=`

) operators compare strings case-sensitively.

The "approximately equal" operator (`≈`

) was introduced in r16284. When comparing two strings, it compares them case-insensitively. When comparing other data types, it behaves like the equality operator (`==`

).

Another exception is with strings. If the **first** datatype is a string, and the second isn't, the latter will be silently converted into a string. Remember that strings are compared alphabetically (with the alphabet here being the characters' ASCII value), just like in a dictionary, in which "smaller" means "would come before".

```
if ( "a" < "b" )
{
print( "This line DOES get printed." );
}
if ( "apple" < "b" )
{
print( "This line DOES get printed." );
}
if ( "1" < 2 )
{
print( "This line DOES get printed." );
}
if ( "1487" < 2 )
{
print( "This line DOES get printed." );
}
if ( "a" < 2 )
{
print( "This line does NOT get printed." );
}
if ( "3" == 3 )
{
print( "This line DOES get printed." );
}
if ( "3.0" == 3 )
{
print( "This line does NOT get printed." );
}
if ( 3 == "3" )
{
print( "This GENERATES AN ERROR!" );
}
if ( "true" == true )
{
print( "This line DOES get printed." );
}
```

Take the habit of always converting your datatypes to avoid unexpected problems.

## Boolean Operators

&& | and |

|| | or |

! | not |

Note that the above operators only work with boolean values & datatypes. To make use of them with other datatypes, you will either need to first perform a Datatype Conversion, or you will need to nest your operations such that a boolean value is used with the boolean operators.

```
if ( true && true )
{
print( "This line DOES get printed (both possibilities proved true)." );
}
if ( true && false )
{
print( "This line does NOT get printed (only one possibility proved true)." );
}
if ( true || false )
{
print( "This line DOES get printed (since at least one of the possibilities proved true)." );
}
if ( ! false )
{
print( "This line DOES get printed (since the not operator converted false to true)." );
}
```

#### Notes

ASH uses Short-circuit_evaluation.

What this means is that in both of these examples, expensive_function() is not evaluated (i.e. is skipped):

```
if ( false && expensive_function() ) {
...
}
```

```
if ( true || expensive_function() ) {
...
}
```

## Operator Precedence

KoLmafia follows Java's Operator Precedence rules with a few exceptions.

(The exceptions being operators that exist in only one or the other; operators that exist in both have the same precedence in both.)

14 | (reserved for postfix ++ and --) |

13 | ! ~ contains remove (reserved for prefix ++ and --) |

12 | ** |

11 | * / % |

10 | + - |

9 | << >> >>> |

8 | < > <= >= |

7 | == != |

6 | & |

5 | ^ (xor) |

5 | | |

3 | && |

2 | || |

1 | (reserved for ?:(ternary conditional)) |

0 | (reserved for assignments) |

Statements inside a () pair are always evaluated first, then in order of precedence as listed above (highest number precedence first), then left-to-right.

```
if ( true || true && false )
{
print( "This line DOES get printed." );
// && has highest precedence
// true or (true && false) returns true
}
if ( ( true && false ) && true )
{
print( "This line does NOT get printed." );
// ( true && false ) is evaluated first since it is inside of parentheses
// so we end up evaluating ( false && true ) which returns false
}
if ( true && ! ( true && false ) )
{
print( "This line DOES get printed." );
// ( true && false ) is evaluated first since it is inside of parentheses
// the ! operator converts the false from ( true && false ) to true
// ( true && true ) returns true
}
```