The above code uses a number of arithmetic operators. Here are the integer
operators organized by precedence and associativity. Precedence and associativity
determine how an expression involving multiple operators is to be read.
For example, how should one read the following?

x + y * u - w - z

E's answer is "((x + (y * u)) - w) - z", because

* is higher precedence than + or -.

+ and - are the same precedence, and

+ and - are left associative.

Higher precedence means that it groups tighter than operators
of lower precedence. Left associative means that it groups left-to-right.
Non-associative means it doesn't group with itself. For example,
in E you can't say "5 == 6 == 7" since == is non-associative.

Boolean Comparisons (non-associative)

Example

Meaning

Expansion

Value

5 == 6

Are they the same?

__equalizer.sameEver(5, 6)

false

5 != 6

Are they different?

__equalizer.sameEver(5, 6).not()

true

5 & 6

bitwise-and

5 and(6)

4

5 | 6

bitwise-or

5 or(6)

7

5 ^ 6

bitwise-xor

5.xor(6)

3

On integers, these do just what you'd expect from any C-tradition language.
Since E's integers are not precision limited, the bitwise operators see
negative integers as having an infinite number of leading one bits, and
the non-negative integers as having an infinite number of leading zero
bits.

Magnitude Comparisons (non-associative)

Example

Meaning

Expansion

Value

5 < 6

less than

5.compareTo(6) belowZero()

true

5 <= 6

less or equal to

5.compareTo(6) atMostZero()

true

5 >= 6

greater or equal to

5.compareTo(6) atLeastZero()

false

5 > 6

greater than

5.compareTo(6) aboveZero()

false

On integers, these have the conventional meaning.

Interval Expressions (non-associative)

Example

Meaning

Expansion

Value

5..9

the integers from 5 inclusive to 9 inclusive

__makeOrderedSpace.op__thru(5, 9)

[5,6,7,8,9]

5..!9

the integers from 5 inclusive to 9 exclusive

__makeOrderedSpace.op__till(5, 9)

[5,6,7,8]

The interval expression makes it especially convenient to form interval
objects. An interval object acts like a consecutive sequence of numbers,
but uses a more compact representation. Intervals are useful, for example,
in iteration:

The reason for the strange syntax "..!" is that inclusive-exclusive
intervals are often the most useful (and least accident prone) but have
no natural notation. "x ..! y" can be thought of as "from
x to, but not, y".

Bit Shift Expressions (left associative)

Example

Meaning

Expansion

Value

5 << 3

arithmetic shift left

5.leftShift(3)

40

5 >> 1

arithmetic shift right

5.leftShift(-1)

2

Since E's integers are not precision limited, the "logical shift"
that appears in some languages would be meaningless. As with the bitwise
operators, negative numbers have an infinite supply of leading one bits
and non-negative numbers have an infinite supply of leading zero bits.

Multiplication is add you'd expect. Division and remainder present an
interesting problem. Integer division cannot of course be exact. E's "/"
always gives the nearest floating point answer, even for cases that have
an exact integer answer. E's "//" (pronounced "floor-divide")
always gives the nearest integer not greater than the actual answer, ie,
rounding towards negative infinity. By contrast, Java's "/"
rounds towards zero. E's integers respond to the "truncDivide"
message with this Java behavior. "%" is the remainder of truncDivide.
"%%" is the remainder of "//", which is equivalent
to the mathematical notion of modulo.

It turns out that modular exponentiation can be calculated vastly faster
than the equivalent modulo of an exponentiation, so E's expansion recognizes
this one case of a three-operand operator expression. Here's a useful
demonstration of a mathematical discovery by Whit Diffee and Martin Hellman:

If base and mod are publicly known, and if Joe and Betty each publicize
only their calculated public numbers, then the above calculation shows
them how they can calculate a new number, eg, 631, that they both agree
on.

In the above example, base, mod, JoeSecret, and BettySecret were chosen
by flinging my fingers at the keyboard. If instead they are chosen well,
then no one who only knows base, mod, JoePublic, and BettyPublic will
be able to calculate the number that Joe and Betty have come to agree
on. This is known as Diffee Hellman Key Agreement.

Exercise for the reader: If the above example used larger numbers, would
this web page be export controlled?

For the numerically savvy, there's another way in which "x
** y %% z" is better than "(x ** y) %% z",
beyond being more efficient. If y is negative the latter expression doesn't
make any sense (and throws an exception) while the former expression calculates
"(x ** y.abs()).modInverse(z)", though once again, more efficiently.

Exponentiation Expression (non associative)

Example

Meaning

Expansion

Value

3 ** 4

exponentiation

3.pow(4)

81

As you'd expect. Negative exponents are not allowed at this time.

Unary Expressions (left associative)

Example

Meaning

Expansion

Value

- 5

twos-complement

5.negate()

-5

~5

bitwise-complement

5.complement()

-6

As you'd expect.

Additional integer Messages

In addition to the messages corresponding to the above operators, integers
respond to the following messages.

? (-5).truncDivide(3)
# value: -1

"truncDivide" is integer division where the answer is rounded
to an integer by rounding towards zero. It correspond to Java's "/"
operator.

On float64s, "ceil", "floor", "round",
and "trunc" are used to get a corresponding integer. They are
defined on integers as well to just return the integer itself. Why? That
way, if you've got a number and you ask for an integer, it works even
if you already have an integer.

? 33.asChar()
# value: '!'

Returns the character whose character code in unicode is 33.

? 33.asFloat64()
# value: 33.0

Converts to a floating point number.

? (-5).abs()
# value: 5

Absolute value.

? 248972.gcd(872346)
# value: 2

Greatest Common Divisor.

Integer Syntax

** To be written

Unless stated otherwise, all text on this page which is either unattributed
or by Mark S. Miller is hereby placed in the public domain.