On this page:
Number
Exact
Inexact
Int
Pos  Int
Neg  Int
Nonneg  Int
Int.in
Real
Pos  Real
Neg  Real
Nonneg  Real
Real.at_  least
Real.above
Real.below
Real.at_  most
Real.in
Rational
Integral
Flonum
Byte
+
-
*
/
**
div
rem
mod
.>
.>=
.<
.<=
math.abs
math.max
math.min
math.floor
math.ceiling
math.round
math.sqrt
math.log
math.exp
math.expt
math.cos
math.sin
math.tan
math.acos
math.asin
math.atan
math.exact
math.inexact
math.real_  part
math.imag_  part
math.magnitude
math.angle
math.numerator
math.denominator
math.gcd
math.lcm
math.random
math.sum
math.product
math.equal
math.less
math.less_  or_  equal
math.greater
math.greater_  or_  equal
math.pi
bits.and
bits.or
bits.xor
bits.not
bits.(<<)
bits.(>>)
bits.(?)
bits.length
bits.field
8.12

6.24 Numbers🔗ℹ

Numbers are comparable, which means that generic operations like < and > work on numbers, while specialized operations like .< and .> work only on numbers.

annotation

Number

Matches any number.

> 5 is_a Number

#true

> 5/2 is_a Number

#true

> #inf is_a Number

#true

> math.sqrt(-1) is_a Number

#true

annotation

Exact

 

annotation

Inexact

Matches exact and inexcat numbers, respectively. An inexact number is one that is represented as a floating-point number or a complex number with an inexact real or imaginary part. These two annotations are mutually exclusive.

> 5 is_a Exact

#true

> 5.0 is_a Inexact

#true

> 5.0 is_a Exact

#false

> 5 is_a Inexact

#false

annotation

Int

 

annotation

PosInt

 

annotation

NegInt

 

annotation

NonnegInt

 

annotation

Int.in(lo_expr inclusivity, hi_expr inclusivity)

 

inclusivity

 = 

ϵ

 | 

~inclusive

 | 

~exclusive

Matches exact integers: all of them, positive integers, negative integers, nonnegative integers, or integers in a given range.

The Int.in annotation constraints a integers to be within the given range, where each end of the range is inclusive by default, but ~inclusive or ~exclusive can be specified.

> 5 is_a Int

#true

> 5 is_a PosInt

#true

> -5 is_a NegInt

#true

> 0 is_a NonnegInt

#true

> 0 is_a Int.in(0, 1 ~exclusive)

#true

> 1 is_a Int.in(0, 1 ~exclusive)

#false

annotation

Real

 

annotation

PosReal

 

annotation

NegReal

 

annotation

NonnegReal

 

annotation

Real.at_least(lo_expr)

 

annotation

Real.above(lo_expr)

 

annotation

Real.below(hi_expr)

 

annotation

Real.at_most(hi_expr)

 

annotation

Real.in(lo_expr inclusivity, hi_expr inclusivity)

The Real annotation matches real numbers (as opposed to imaginary numbers like the result of math.sqrt(-1)). The PosReal, NegReal, and NonnegReal annotatiosn match positive, negative, and non-negative real numbers, respectively.

The Real.at_least, Real.above, Real.below, and Real.at_most annotations furher constrain the number to be equal to or greater than, greater than, less then, or equal to or less than the given number, respectively.

The Real.in annotation constraints a real number to be within the given range, where each end of the range is inclusive by default, but ~inclusive or ~exclusive can be specified.

> 5 is_a Real

#true

> 5.0 is_a Real

#true

> 5.1 is_a Real

#true

> #inf is_a Real

#true

> math.sqrt(-1) is_a Real

#false

> 1 is_a Real.at_least(1)

#true

> 1 is_a Real.above(1)

#false

> 0 is_a Real.in(0, 1 ~exclusive)

#true

> 1 is_a Real.in(0, 1 ~exclusive)

#false

annotation

Rational

Matches the same numbers as Real except for #inf, #neginf, and #nan.

> 5 is_a Rational

#true

> #inf is_a Rational

#false

annotation

Integral

Matches the same numbers as Int plus real numbers that have no fractional component.

> 5 is_a Integral

#true

> 5.0 is_a Integral

#true

> 5.1 is_a Integral

#false

annotation

Flonum

Matches real numbers that are represented as floating-point numbers.

> 5.0 is_a Flonum

#true

> #inf is_a Flonum

#true

> 5 is_a Flonum

#false

> 5/2 is_a Flonum

#false

annotation

Byte

Matches integers in the range 0 ro 255 (inclusive).

> 5 is_a Byte

#true

> 256 is_a Byte

#false

operator

operator ((x :: Number) + (y :: Number)) :: Number

 

operator

operator ((x :: Number) - (y :: Number)) :: Number

 

operator

operator (- (x :: Number)) :: Number

 

operator

operator ((x :: Number) * (y :: Number)) :: Number

 

operator

operator ((x :: Number) / (y :: Number)) :: Number

 

operator

operator ((x :: Number) ** (y :: Number)) :: Number

The usual arithmetic operators with the usual precedence.

Note that forms like +1, -1, and 1/2 are immediate numbers, as opposed to uses of the +, -, and / operators.

> 1+2

3

> 3-4

-1

> - 4

-4

> 5*6

30

> 8 / 2

4

> 7 / 2

7/2

> 7.0/2

3.5

> 1+2*3

7

> 2**10

1024

> 6 / 2 * 3

9

operator

operator ((x :: Integral) div (y :: Integral)) :: Integral

 

operator

operator ((x :: Integral) rem (y :: Integral)) :: Integral

 

operator

operator ((x :: Integral) mod (y :: Integral)) :: Integral

Integer division (truncating), remainder, and modulo operations. These operators have stronger pecedence than + and - but no precedence relationship to *, /, or **.

> 7 div 5

1

> 7 rem 5

2

> 7 mod 5

2

> 7 mod -5

-3

operator

operator ((x :: Number) .> (y :: Number)) :: Boolean

 

operator

operator ((x :: Number) .>= (y :: Number)) :: Boolean

 

operator

operator ((x :: Number) .< (y :: Number)) :: Boolean

 

operator

operator ((x :: Number) .<= (y :: Number)) :: Boolean

The usual comparsion operators on numbers prefixed with . to distinsguish them from generic operations like < on comparable values. See also .= and .!=.

> 1 .< 2

#true

> 3 .>= 3.0

#true

function

fun math.abs(x :: Real) :: Real

 

function

fun math.max(x :: Real, y :: Real, ...) :: Real

 

function

fun math.min(x :: Real, y :: Real, ...) :: Real

 

function

fun math.floor(x :: Real) :: Real

 

function

fun math.ceiling(x :: Real) :: Real

 

function

fun math.round(x :: Real) :: Real

 

function

fun math.sqrt(x :: Number) :: Number

 

function

fun math.log(x :: Number, base :: Number = math.exp(1))

  :: Number

 

function

fun math.exp(x :: Number) :: Number

 

function

fun math.expt(base :: Number, power :: Number) :: Number

 

function

fun math.cos(x :: Number) :: Number

 

function

fun math.sin(x :: Number) :: Number

 

function

fun math.tan(x :: Number) :: Number

 

function

fun math.acos(x :: Number) :: Number

 

function

fun math.asin(x :: Number) :: Number

 

function

fun math.atan(x :: Number) :: Number

 

function

fun math.atan(y :: Real, x :: Real) :: Number

The usual functions on numbers.

> math.abs(-1.5)

1.5

> math.min(1, 2)

1

> math.max(1, 2)

2

> math.floor(1.5)

1.0

> math.ceiling(1.5)

2.0

> math.round(1.5)

2.0

> math.sqrt(4)

2

> math.cos(3.14)

-0.9999987317275395

> math.sin(3.14)

0.0015926529164868282

> math.tan(3.14 / 4)

0.9992039901050427

> math.acos(1)

0

> math.asin(1)

1.5707963267948966

> math.atan(0.5)

0.4636476090008061

> math.atan(1, 2)

0.4636476090008061

> math.log(2.718)

0.999896315728952

> math.exp(1)

2.718281828459045

function

fun math.exact(x :: Number) :: Exact

 

function

fun math.inexact(x :: Number) :: Inexact

Converts a number to ensure that it is exact or inexact, respectively. Some real numbers, such as #inf, cannot be made exact.

> math.exact(5.0)

5

> math.inexact(5)

5.0

function

fun math.real_part(x :: Number) :: Real

 

function

fun math.imag_part(x :: Number) :: Real

 

function

fun math.magnitude(x :: Number) :: Real

 

function

fun math.angle(x :: Number) :: Real

Operations on complex numbers.

> math.real_part(5)

5

> math.real_part(math.sqrt(-1))

0

> math.imag_part(math.sqrt(-1))

1

> math.magnitude(1 + math.sqrt(-1))

1.4142135623730951

> math.angle(1 + math.sqrt(-1))

0.7853981633974483

Coerces q to an exact number, finds the numerator of the number expressed in its simplest fractional form, and returns this number coerced to the exactness of q.

> math.numerator(256/6)

128

> math.denominator(256/6)

3

> math.denominator(0.125)

8.0

function

fun math.gcd(q :: Rational, ...) :: Rational

 

function

fun math.lcm(q :: Rational, ...) :: Rational

Coerces each q to an exact number and finds the greatest common divisor or least common multiple.

For non-integer arguments, the result for math.gcd is the greatest common divisor of the numerators divided by the least common multiple of the denominators. The result for math.lcm for non-integer arguments is the absolute value of the product divided by the math.gcd of the arguments.

If no arguments are provided, the result of math.gcd is 0 and the result of math.lcm is 1. If all arguments for math.gcd are zero, the result is zero. If any argument for math.lcm is zero, the result is zero, and the result is exact 0 if any argument is exact 0.

> math.gcd(2, 3, 7)

1

> math.gcd(4, 2, 16)

2

> math.lcm(2, 3, 7)

42

> math.lcm(4, 10, 2)

20

> math.gcd()

0

> math.lcm()

1

function

fun math.random()

  :: Real.in(0 ~exclusive, 1 ~exclusive)

 

function

fun math.random(n :: PosInt)

  :: Int.in(0, n ~exclusive)

 

function

fun math.random(start :: Int, end :: Int)

  :: Int.in(start, end ~exclusive)

When called with no arguments, returns a random real number between 0 (exclusive) and 1 (exclusive).

When called with n, returns a random integer between 0 (inclusive) and n (exclusive).

When called with start and end, returns a random integer between start (inclusive) and end (exclusive).

See also Random.random.

> math.random()

0.5348255534758128

> math.random(17)

13

> math.random(1, 42)

21

function

fun math.sum(n :: Number, ...) :: Number

 

function

fun math.product(n :: Number, ...) :: Number

Generalizations of + and * to any number of arguments.

> math.sum()

0

> math.sum(1, 2, 3, 4)

10

> math.product(1, 2, 3, 4)

24

function

fun math.equal(n :: Number, ...) :: Boolean

 

function

fun math.less(n :: Real, ...) :: Boolean

 

function

fun math.less_or_equal(n :: Real, ...) :: Boolean

 

function

fun math.greater(n :: Real, ...) :: Boolean

 

function

fun math.greater_or_equal(n :: Real, ...) :: Boolean

Generalizations of .=, <, <=, >, and >= to any number of arguments. The result is always #true for zero or one arguments.

> math.less()

#true

> math.less(1)

#true

> math.less(2, 1)

#false

> math.less(1, 2, 3, 4)

#true

> math.less(1, 2, 3, 0)

#false

An appromation of π, the ratio of a circle’s circumference to its diameter.

> math.pi

3.141592653589793

operator

operator ((n :: Int) bits.and (m :: Int)) :: Int

 

operator

operator ((n :: Int) bits.or (m :: Int)) :: Int

 

operator

operator ((n :: Int) bits.xor (m :: Int)) :: Int

 

operator

operator (bits.not (n :: Int)) :: Int

 

operator

operator ((n :: Int) bits.(<<) (m :: NonnegInt)) :: Int

 

operator

operator ((n :: Int) bits.(>>) (m :: NonnegInt)) :: Int

 

operator

operator ((n :: Int) bits.(?) (m :: NonnegInt)) :: Boolean

 

function

fun bits.length(n :: Int) :: Int

 

function

fun bits.field(n :: Int,

               start :: NonnegInt,

               end :: NonnegInt)

  :: Int

Bitwise operations on integers interpreted as a semi-infinite two’s complement representation:

> 5 bits.and 3

1

> 5 bits.or 3

7

> 5 bits.xor 3

6

> bits.not 3

-4

> 5 bits.(<<) 2

20

> 5 bits.(>>) 2

1

> bits.length(2)

2

> bits.length(-2)

1

> bits.field(255, 1, 4)

7