How do arithmetic and mathematical operators work in EK9?
← Operators and Expressions · Ref: Q240
EK9 provides binary arithmetic operators, unary mathematical operators, and specialized math operations. All arithmetic and math operators MUST be pure.
BINARY ARITHMETIC
The +, -, *, / operators are pure, take 1 argument, and return a new value of the same or compatible type. They do NOT modify the original.
result <- a + b quotient <- total / count
The ^ operator computes power: base ^ exponent.
squared <- value ^ 2
UNARY OPERATORS
The - operator as unary (0 arguments) negates a numeric value:
negative <- -positive
For Integer and Float, unary - returns the negated value. The ~ operator is NOT for numeric negation. It is logical NOT for Boolean and bitwise NOT for Bits.
The ! operator computes factorial (returns result, 0 arguments):
result <- 5!
Factorial is defined on Integer.
SQRT AND ABS
The sqrt operator returns the square root. The abs operator returns the absolute value. Both are pure, take 0 arguments, and return the same type.
root <- sqrt value magnitude <- abs negativeNumber
MOD VS REM
Both mod and rem are pure, take 1 argument, and return a result. The critical difference:
mod (modulus): Result ALWAYS has the same sign as the divisor (mathematical modulus). rem (remainder): Result has the same sign as the dividend (truncated division remainder).
With positive numbers they are identical:
7 mod 3 yields 1 7 rem 3 yields 1
With negative numbers they differ:
-7 mod 3 yields 2 (always positive when divisor is positive) -7 rem 3 yields -1 (preserves dividend sign)
Use mod for cyclic operations (array indexing, clock arithmetic). Use rem for mathematical remainder after division.
See Q238 for the complete operator set. See Q241 for mutation operators (+=, -=). See Q39 for integer and float basics.
Example
defines module qa.operators.arithmetic defines program ArithmeticDemo() stdout <- Stdout() // === BINARY ARITHMETIC === a <- 10 b <- 3 stdout.println(`Add: ${a + b}`) stdout.println(`Subtract: ${a - b}`) stdout.println(`Multiply: ${a * b}`) stdout.println(`Divide: ${a / b}`) // === POWER === base <- 2 squared <- base ^ 3 stdout.println(`Power: ${squared}`) // === MOD VS REM === stdout.println(`7 mod 3: ${7 mod 3}`) stdout.println(`7 rem 3: ${7 rem 3}`) // With negative numbers - the critical difference stdout.println(`-7 mod 3: ${-7 mod 3}`) stdout.println(`-7 rem 3: ${-7 rem 3}`) // === UNARY NEGATE (unary minus) === positive <- 42 negative <- -positive stdout.println(`Negate: ${negative}`) // === ABS AND SQRT === negNum <- -25 stdout.println(`Abs: ${abs negNum}`) floatVal <- 16.0 stdout.println(`Sqrt: ${sqrt floatVal}`)
Common mistakes
E50060 — EK9 Integer has no absoluteValue() method. Use the prefix operator 'abs value'. While value.abs() also works, Java-style verbose names like absoluteValue() do not exist. See ek9 -h E50060 for details.
Incorrect:
negNum.absoluteValue()
Correct:
abs negNum
E50060 — EK9 Float has no squareRoot() method. Use the prefix operator 'sqrt value'. While value.sqrt() also works, Java-style verbose names like squareRoot() do not exist. See ek9 -h E50060 for details.
Incorrect:
floatVal.squareRoot()
Correct:
sqrt floatVal
Other ways to ask this
- What is the difference between mod and rem in EK9?
- How do I use sqrt and abs in EK9?
- What mathematical operators does EK9 provide?
Coming from another language?
Java: % is remainder (not modulus), Math.floorMod() for true modulus, Math.abs(), Math.sqrt(). Python: % is true modulus (matches divisor sign), divmod() for both. Rust: % is remainder, rem_euclid() for modulus. Go: % is remainder, no built-in modulus. Kotlin: % is remainder, mod() for modulus. JavaScript: % is remainder, no built-in modulus. EK9: separate mod (true modulus) and rem (remainder) operators, plus sqrt, abs, ! (factorial), unary - (negate), ^ (power).
Keywords: expression, abs, multiply, operator, divide, remainder, mod, math, sqrt, factorial, add, subtract, power, modulus, negate, arithmetic, rem