7.2 Numbers
Real numbers are comparable, which means that generic operations like < and > work on real numbers, while specialized operations like .< and .> work only on real numbers.
annotation | |
Although only real numbers are comparable, to make the results of arithmetic operations easier to compare in static mode, static information associated by Number specifies Real-specific Comparable operations.
#true
#true
#true
#true
#true
#true
#false
#false
annotation | ||||||||||||
| ||||||||||||
annotation | ||||||||||||
| ||||||||||||
annotation | ||||||||||||
| ||||||||||||
annotation | ||||||||||||
| ||||||||||||
annotation | ||||||||||||
| ||||||||||||
|
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.
#true
#true
#true
#true
#true
#false
annotation | |
| |
annotation | |
| |
annotation | |
| |
annotation | |
| |
annotation | |
| |
annotation | |
| |
annotation | |
| |
annotation | |
| |
annotation | |
The Real.at_least, Real.above, Real.below, and Real.at_most annotations further 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.
#true
#true
#true
#true
#false
> 1 is_a Real.at_least(1)
#true
> 1 is_a Real.above(1)
#false
#true
#false
annotation | |
#true
#false
annotation | |
#true
#true
#false
annotation | |
#true
#true
#false
#false
annotation | |
#true
#false
annotation | |
#true
#false
#true
expression | |
| |
| |
repetition | |
| |
| |
binding operator | |
|
> Byte#"a"
97
| ~else: "no"
"yes"
> Byte#"too long"
Byte: expected a literal single-byte byte string
Byte: expected a literal single-byte byte string
operator | |
| |
operator | |
| |
operator | |
| |
operator | |
| |
operator | |
| |
operator | |
When expressions for both x and y have static information from Flonum (or just x in the case of prefix the - operator), then the arithmetic operation is specialized to one that expects Flonum arguments. If the static information is incorrect (e.g., because a non-checking :~ is used), then a run-time error is reported if an argument is not a Flonum.
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
7
> 2**10
1024
9
operator | |
| |
operator | |
| |
operator | |
> 7 div 5
1
> 7 rem 5
2
> 7 mod 5
2
> 7 mod -5
-3
operator | |
| |
operator | |
| |
operator | |
| |
operator | |
These comparisons are specialized like + for arguments with Flonum static information.
> 1 .< 2
#true
> 3 .>= 3.0
#true
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
| ||
function | ||
When a call to the math.abs, math.max, math.min, math.floor, math.ceiling, math.round, math.truncate, math.sin, math.cos, or math.tan function has arguments with static information from Flonum, then the functions are specialized to ones that require Flonum arguments, similar to operations like +. The other functions are not specialized, because they do not always produce Flonum results for Flonum arguments.
> 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
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
> math.exact(5.0)
5
> math.inexact(5)
5.0
function | |
| |
function | |
| |
function | |
| |
function | |
> 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
function | |
| |
function | |
> math.numerator(256/6)
128
> math.denominator(256/6)
3
> math.denominator(0.125)
8.0
function | |
| |
function | |
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 | ||
| ||
function | ||
| ||
| ||
function | ||
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 | |
| |
function | |
> math.sum()
0
> math.sum(1, 2, 3, 4)
10
> math.product(1, 2, 3, 4)
24
function | |
| |
function | |
| |
function | |
| |
function | |
| |
function | |
> 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
> math.pi
3.141592653589793
operator | ||||
| ||||
operator | ||||
| ||||
operator | ||||
| ||||
operator | ||||
| ||||
operator | ||||
| ||||
operator | ||||
| ||||
operator | ||||
| ||||
function | ||||
| ||||
function | ||||
|
bits.and, bits.or (inclusive), bits.xor, work on pairs of bits from n and m;
bits.not inverts every bit in n;
bits.(<<) and bits.(>>) perform a left shift or arithmetic right shift of n by m bits;
bits.(?) reports whether the bit at position m (counting from 0 as the least-significant bit) is set within n;
bits.length reports the number of bits that remain in n if all identical leading bits (0s for a position n or 1s for a negative n) are removed; and
bits.field produces the integer represented by bits start (inclusive) through end (exclusive) of n.
> 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