# Operators

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

## 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

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. Also, == is case-insensitive with respect to strings.

```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 get printed." );
}```

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
}```