By Brandon Wu, May 2020
real is the SML type of real or floating-point numbers. As in other programming languages, reals in SML are restricted to finite machine representations, which means that they cannot represent every real number with perfect precision. For this reason, generally in this course we will prefer the use of
ints when performing numeric operations.
A real number is a sequence of numbers, followed by a decimal point, followed by another sequence of numbers. This includes examples such as
3.14159. Reals are noteworthy in that they are not equality types, which means that they cannot be compared for equality with the
= operator. In addition, they cannot be pattern matched upon. This means that when designing programs with specific behavior based on equality with a specific real number, they should instead be written to operate within some degree of precision of the real number in question. For instance:
val equalThreshold = 0.000001 fun isZero (x : real) : bool = Real.abs x < equalThreshold
This function simply prespecifies a (small) range, within which a number can be considered to be "equal" to 0. It uses the function
Real.abs to check if the real number in question is within that threshold of zero, in either direction. In this way, we can approximate some test for equality, up to some degree of acceptable precision.
Real numbers similarly have access to some of the basic arithmetic operations as integers. In particular, they have:
(op +) : real * real -> real (op -) : real * real -> real (op *) : real * real -> real (op /) : real * real -> real
Note that all but the last operator are also defined to work on
int types. This may seem to violate type safety, however this is just an example of those functions being overloaded. There are two "copies" of, for instance, the
+ operator - one that has type
int * int -> int and one with type
real * real -> real. Notably, however, it only works on either both ints or both reals - it is not defined on both. As such, SML can infer from its arguments whether it should use the
int or the
real variant, and similarly for
div, however, is only defined for integers -
/ is the counterpart for division on the real numbers.
While not defined for equality, reals can still be compared to one another.
(op <) : real * real -> bool (op >) : real * real -> bool (op <=) : real * real -> bool (op >=) : real * real -> bool
These operations are similarly overloaded, and will also work on integers.
Real is bound as part of the SML Basis. It has access to a few useful functions, including:
Real.toString : real -> string Real.compare : real * real -> order Real.abs : real -> real
Real.toString is the standard function that transforms a real number into its corresponding string representation,
Real.compare on two reals returns
GREATER depending on their relative magnitudes, and
Real.abs returns the absolute value of the real number in question.