WhizzML Reference Manual
4.5 Numbers
4.5.1 Numerical type predicates
Predicates checking whether any value is a number, integer or real.
(number? obj) \(\rightarrow \) boolean
(integer? obj) \(\rightarrow \) boolean
(real? obj) \(\rightarrow \) boolean
(integer? 0.0) ;; => false
(real? "hello!") ;; => false
(real? 1) ;; => true
(integer? 1) ;; => true
4.5.2 Arithmetic operators
The basic arithmetic operators take one or more arguments and are represented by their usual symbols:
(+ num1 …) \(\rightarrow \) number
(- num1 …) \(\rightarrow \) number
(* num1 …) \(\rightarrow \) number
(/ num1 …) \(\rightarrow \) number
Division raises error code -10 if division by zero. If passed only one argument, / computes its inverse.
In addition, the standard library includes the following binary and unary operators on numbers:
(rem int1 int2) \(\rightarrow \) integer
Computes the remainder of dividing int1 by int2. Raises error code -10 if the latter is zero.
(div int1 int2) \(\rightarrow \) integer
Computes the integer division num1 by int2. Raises error code -10 if the latter is zero.
(sqrt num1) \(\rightarrow \) number
Computes the square root of its argument. Raises error code -30 if passed a negative number.
(+ 1) ;; => 1
(+ 1 -1) ;; => 0
(- 23.8 18.2) ;; => 42.0
(/ 2) ;; => 0.5
(/ 1 2 3) ;; => 0.16666667
(rem 23 3) ;; => 2
(div 45 7) ;; => 6
(sqrt 24) ;; => 4.898979485566356
(sqrt 0.144) ;; => 0.3794733192202055
4.5.3 Numeric coercion and parsing
The following operators act on any number, returning an integer in all cases:
(abs num) \(\rightarrow \) integer
The absolute value of its argument.
(ceil num) \(\rightarrow \) integer
The ceiling, that is, the lowest integer greater than or equal to the given value.
(floor num) \(\rightarrow \) integer
The floor of a number is the biggest integer less than or equal to the given number.
(round num) \(\rightarrow \) integer
Rounding finds the integer value that is closest to the given number.
(abs -21) ;; => 21
(abs 3.0) ;; => 3.0
(ceil 23.3) ;; => 24
(ceil -128.2) ;; => -128
(floor 12.8) ;; => 12
(floor -12.3) ;; => -13
(round 1.2) ;; => 1
(round 1.5) ;; => 2
(read-number str) \(\rightarrow \) number
The standard library provides read-number to parse a string representing a number, using any of the accepted number literal expressions in WhizzML. This procedure raises error code -30 (domain error) if passed a string that cannot be parsed.
(read-number "0.1232") ;; => 0.1232
(read-number "0.1232a") ;; => Error
(read-number "-32") ;; => -32
(read-number "0x32") ;; => 50 (hexadecimal notation)
(read-number "032") ;; => 26 (octal notation)
(read-number "2r111") ;; => 7 (explicit base)
(read-number "3/2") ;; => 3/2 (rational number)
4.5.4 Comparisons
(< num1 …) \(\rightarrow \) boolean
(<= num1 …) \(\rightarrow \) boolean
(> num1 …) \(\rightarrow \) boolean
(>= num1 …) \(\rightarrow \) boolean
Comparison operators (like, e.g. <) are multivariadic and can take more than two arguments, so that, say, (< x y z) is equivalent to (and (< x y) (< y z)), or the mathematical expression x < y < z.
(< 1 2) ;; => true
(<= 0 0 3) ;; => true
(> -19 -18) ;; => false
(> -19 -20 -21) ;; => true
(<= 1 1 2 2 2 3 4 44) ;; => true
(< 0) ;; => true
(< -1) ;; => true
(< 12.343) ;; => true
Comparison operators can also take a single argument, in which case they always evaluate to true
Convenience predicates for direct comparison to zero and parity are also provided:
(zero? num) \(\rightarrow \) boolean
(positive? num) \(\rightarrow \) boolean
(negative? num) \(\rightarrow \) boolean
(even? int) \(\rightarrow \) boolean
(odd? int) \(\rightarrow \) boolean
(zero? 0) ;; => true
(zero? 0.0) ;; => true
(zero? -2) ;; => false
(positive? 0) ;; => false
(positive? 0.1) ;; => true
(negative? 0) ;; => false
(negative? 0.0) ;; => false
(even? 0) ;; => true
(odd? 3) ;; => true
Furthermore, WhizzML provides procedures for computing the maximum and minimum of any number of arguments:
(min num1 …) \(\rightarrow \) number
(max num1 …) \(\rightarrow \) number
(max 10) ;; => 10
(max -1 -20.0 30 10.2) ;; => 10
(min -1.1) ;; => -1.1
(min (sqrt 2) (sqrt 3)) ;; => 1.4142135623730951
4.5.5 Transcedental functions
Common non-algebraic functions on numbers are also available:
(log num) \(\rightarrow \) number
(log2 num) \(\rightarrow \) number
(log10 num) \(\rightarrow \) number
Logarithms in base \(e\), 2 and 10. These procedures take a positive number as argument, and raise error code -30 otherwise.
(pow num1 num2) \(\rightarrow \) number
(exp num1) \(\rightarrow \) number
The general power function returns \(num1^{num2}\), and exp uses \(e\) as its base, computing \(e^{num1}\).
(sin num1) \(\rightarrow \) number
(cos num1) \(\rightarrow \) number
(tan num1) \(\rightarrow \) number
Standard trigonometric functions: sine, cosine and tanget. For all of them, num1 is an angle in radians. We also provide their inverses:
(asin num1) \(\rightarrow \) number
(acos num1) \(\rightarrow \) number
(atan num1) \(\rightarrow \) number
Both asin and acos take a number in the interval \([1, -1]\), raising error code -30 otherwise.
(to-degress num1) \(\rightarrow \) number
(to-radians num1) \(\rightarrow \) number
Conversion functions from radians to degrees and vice versa.
(sinh num1) \(\rightarrow \) number
(cosh num1) \(\rightarrow \) number
(tanh num1) \(\rightarrow \) number
These are the standard hyperbolic functions.
(gamma num1) \(\rightarrow \) number
The gamma function for real-valued arguments is also available. Note that it is undefined for non-positive integer arguments (including 0).
(log 2) ;; => 0.6931471805599453
(log (exp 1)) ;; => 1.0
(pow 4 (/ 1 2)) ;; => 2.0
(+ (pow (sin 1.2) 2) (pow (cos 1.2) 2)) ;; => 1.0
(tan (atan -1.2)) ;; => -1.2
(sinh 23.32) ;; => 6.709919691913042E9
(gamma 2) ;; => 1.0000000000000002
4.5.6 Random number generators
Each instance of a WhizzML runtime has an implicit random number generator (RNG). The random number series generated by this RNG are accesible via the following standard procedures omitting the optional argument rnd-id in all cases.
(rand [rng-id]) \(\rightarrow \) number
(rand-range num1 num2 [rng-id]) \(\rightarrow \) number
(rand-int num1 [rng-id]) \(\rightarrow \) integer
(set-rng-seed obj [rng-id]) \(\rightarrow \) boolean
The rand procedure generates a random number in the interval \([0, 1]\), whereas rand-range uses the range \([\mathrm{num1}, \mathrm{num2}]\) (with both ends arbitrary numbers). Finally, rand-int returns an integer between 0 and its argument.
The implicit RNG is seeded at random every time a virtual machine is started, so that two runs of the same program using the functions above will in general obtain different number sequences from the generator. To produce deterministic results, you can seed the RNG using set-rng-seed and providing any WhizzML value as seed.
(rand) ;; => 0.5778650511056185
(rand-int 2313) ;; => 501
(rand-range -10 3) ;; => 1.4949024706147611
(set-rng-seed "a seed") ;; => true
Instead of using the implicit RNG, you can create your own RNG instances via create-rng, and use the returned identifier as the rng argument in the functions above.
(create-rng [obj]) \(\rightarrow \) rng-id
The value returned by create-rng is a unique identifier for the RNG just created.
(define rng-id (create-rng 42)) ;; any value can be used as seed
(rand rng-id) ;; => 0.13599370513111353
(rand-int 100 rng-id) ;; => 59
(rand-int 100 rng-id) ;; => 10
(rand-range -10 10 rng-id) ;; => -2.855083905160427
(set-rng-seed rng-id "whizzml") ;; => true
You should treat the random indentifier value as an opaque token. Everytime the seed of an RNG is set, the generator starts over, even if the seed is the same that was used before.
Typically, if you are writing a library that uses random numbers and want to make it deterministic, you will be using in it your own RNG, created via create-rng with an appropriate key. In that way, you won’t interfere with other libraries or scripts using the library at hand, nor get affected by other code setting the implicit RNG’s seed.
4.5.7 Basic statistics
(mean list) \(\rightarrow \) number
(variance list) \(\rightarrow \) number
(stdev list) \(\rightarrow \) number
(chi-squared-test num int) \(\rightarrow \) number
mean computes the mean value of a list of numbers, variance their variance and stdev their standard deviation. chi-squared-test returns the p-value for a given value and degrees of freedom.
mean will raise error code -20 if passed an empty list, and both variance and stdev signal code -25 if passed a list with less than two numbers. chi-squared-test will raise error code -20 if the first argument is negative, or the second argument is either non-positive or non-integer.