Numerics¶
Numeric primitives are defined in a generic manner, by operators indexed over a bit width
Some operators are non-deterministic, because they can return one of several possible results (such as different NaN values). Technically, each operator thus returns a set of allowed values. For convenience, deterministic results are expressed as plain values, which are assumed to be identified with a respective singleton set.
Some operators are partial, because they are not defined on certain inputs. Technically, an empty set of results is returned for these inputs.
In formal notation, each operator is defined by equational clauses that apply in decreasing order of precedence.
That is, the first clause that is applicable to the given arguments defines the result.
In some cases, similar clauses are combined into one by using the notation
Note
For example, the
This definition is to be read as a shorthand for the following expansion of each clause into two separate ones:
Numeric operators are lifted to input sequences by applying the operator element-wise, returning a sequence of results. When there are multiple inputs, they must be of equal length.
Note
For example, the unary operator
The binary operator
Conventions:
The meta variable
is used to range over single bits.The meta variable
is used to range over (signless) magnitudes of floating-point values, including and .The meta variable
is used to range over (signless) rational magnitudes, excluding or .The notation
denotes the inverse of a bijective function .Truncation of rational values is written
, with the usual mathematical definition:
Saturation of integers is written
and . The arguments to these two functions range over arbitrary signed integers.Unsigned saturation,
clamps to between and :Signed saturation,
clamps to between and :
Representations¶
Numbers and numeric vectors have an underlying binary representation as a sequence of bits:
The first case of these applies to representations of both integer value types and packed types.
Each of these functions is a bijection, hence they are invertible.
Integers¶
Integers are represented as base two unsigned numbers:
Boolean operators like
Floating-Point¶
Floating-point values are represented in the respective binary format defined by IEEE 754 (Section 3.4):
where
Vectors¶
Numeric vectors of type
This function is a bijection on
Storage¶
When a number is stored into memory, it is converted into a sequence of bytes in little endian byte order:
Again these functions are invertible bijections.
Integer Operations¶
Sign Interpretation¶
Integer operators are defined on
This function is bijective, and hence invertible.
Boolean Interpretation¶
The integer result of predicates – i.e., tests and relational operators – is defined with the help of the following auxiliary function producing the value
¶
Return the result of adding
and modulo .
¶
Return the result of subtracting
from modulo .
¶
Return the result of multiplying
and modulo .
¶
If
is , then the result is undefined.Else, return the result of dividing
by , truncated toward zero.
Note
This operator is partial.
¶
Let
be the signed interpretation of .Let
be the signed interpretation of .If
is , then the result is undefined.Else if
divided by is , then the result is undefined.Else, return the result of dividing
by , truncated toward zero.
Note
This operator is partial.
Besides division by
¶
If
is , then the result is undefined.Else, return the remainder of dividing
by .
¶
Let
be the signed interpretation of .Let
be the signed interpretation of .If
is , then the result is undefined.Else, return the remainder of dividing
by , with the sign of the dividend .
¶
Return the bitwise negation of
.
¶
Return the bitwise conjunction of
and .
¶
Return the bitwise conjunction of
and the bitwise negation of .
¶
Return the bitwise disjunction of
and .
¶
Return the bitwise exclusive disjunction of
and .
¶
Let
be modulo .Return the result of shifting
left by bits, modulo .
¶
Let
be modulo .Return the result of shifting
right by bits, extended with bits.
¶
Let
be modulo .Return the result of shifting
right by bits, extended with the most significant bit of the original value.
¶
Let
be modulo .Return the result of rotating
left by bits.
¶
Let
be modulo .Return the result of rotating
right by bits.
¶
Return the count of leading zero bits in
; all bits are considered leading zeros if is .
¶
Return the count of trailing zero bits in
; all bits are considered trailing zeros if is .
¶
Return the count of non-zero bits in
.
¶
Return
if is zero, otherwise.
¶
Return
if equals , otherwise.
¶
Return
if does not equal , otherwise.
¶
Return
if is less than , otherwise.
¶
Let
be the signed interpretation of .Let
be the signed interpretation of .Return
if is less than , otherwise.
¶
Return
if is greater than , otherwise.
¶
Let
be the signed interpretation of .Let
be the signed interpretation of .Return
if is greater than , otherwise.
¶
Return
if is less than or equal to , otherwise.
¶
Let
be the signed interpretation of .Let
be the signed interpretation of .Return
if is less than or equal to , otherwise.
¶
Return
if is greater than or equal to , otherwise.
¶
Let
be the signed interpretation of .Let
be the signed interpretation of .Return
if is greater than or equal to , otherwise.
¶
Let
be the result of computing .Return
.
¶
Let
be the bitwise conjunction of and .Let
be the bitwise negation of .Let
be the bitwise conjunction of and .Return the bitwise disjunction of
and .
¶
Let
be the signed interpretation of .If
is greater than or equal to , then return .Else return the negation of j, modulo
.
¶
Return the result of negating
, modulo .
¶
Return
if is , return otherwise.
¶
Return
if is , return otherwise.
¶
Return
if is , return otherwise.
¶
Return
if is , return otherwise.
¶
Let
be the result of adding and .Return
.
¶
Let
be the signed interpretation ofLet
be the signed interpretation ofLet
be the result of adding and .Return
.
¶
Let
be the result of subtracting from .Return
.
¶
Let
be the signed interpretation ofLet
be the signed interpretation ofLet
be the result of subtracting from .Return
.
¶
Let
be the result of adding , , and .Return the result of dividing
by , truncated toward zero.
¶
Return the result of
.
Floating-Point Operations¶
Floating-point arithmetic follows the IEEE 754 standard, with the following qualifications:
All operators use round-to-nearest ties-to-even, except where otherwise specified. Non-default directed rounding attributes are not supported.
Following the recommendation that operators propagate NaN payloads from their operands is permitted but not required.
All operators use “non-stop” mode, and floating-point exceptions are not otherwise observable. In particular, neither alternate floating-point exception handling attributes nor operators on status flags are supported. There is no observable difference between quiet and signalling NaNs.
Note
Some of these limitations may be lifted in future versions of WebAssembly.
Rounding¶
Rounding always is round-to-nearest ties-to-even, in correspondence with IEEE 754 (Section 4.3.1).
An exact floating-point number is a rational number that is exactly representable as a floating-point number of given bit width
A limit number for a given floating-point bit width
A candidate number is either an exact floating-point number or a positive or negative limit number for the given bit width
A candidate pair is a pair
A real number
If
is , then return .Else if
is an exact floating-point number, then return .Else if
greater than or equal to the positive limit, then return .Else if
is less than or equal to the negative limit, then return .Else if
and are a candidate pair such that , then:If
, then let be .Else if
, then let be .Else if
and the significand of is even, then let be .Else, let
be .
If
is , then:If
, then return .Else, return
.
Else if
is a limit number, then:If
, then return .Else, return
.
Else, return
.
where:
NaN Propagation¶
When the result of a floating-point operator other than
If the payload of all NaN inputs to the operator is canonical (including the case that there are no NaN inputs), then the payload of the output is canonical as well.
Otherwise the payload is picked non-deterministically among all arithmetic NaNs; that is, its most significant bit is
and all others are unspecified.
This non-deterministic result is expressed by the following auxiliary function producing a set of allowed outputs from a set of inputs:
¶
If either
or is a NaN, then return an element of .Else if both
and are infinities of opposite signs, then return an element of .Else if both
and are infinities of equal sign, then return that infinity.Else if either
or is an infinity, then return that infinity.Else if both
and are zeroes of opposite sign, then return positive zero.Else if both
and are zeroes of equal sign, then return that zero.Else if either
or is a zero, then return the other operand.Else if both
and are values with the same magnitude but opposite signs, then return positive zero.Else return the result of adding
and , rounded to the nearest representable value.
¶
If either
or is a NaN, then return an element of .Else if both
and are infinities of equal signs, then return an element of .Else if both
and are infinities of opposite sign, then return .Else if
is an infinity, then return that infinity.Else if
is an infinity, then return that infinity negated.Else if both
and are zeroes of equal sign, then return positive zero.Else if both
and are zeroes of opposite sign, then return .Else if
is a zero, then return .Else if
is a zero, then return negated.Else if both
and are the same value, then return positive zero.Else return the result of subtracting
from , rounded to the nearest representable value.
Note
Up to the non-determinism regarding NaNs, it always holds that
¶
If either
or is a NaN, then return an element of .Else if one of
and is a zero and the other an infinity, then return an element of .Else if both
and are infinities of equal sign, then return positive infinity.Else if both
and are infinities of opposite sign, then return negative infinity.Else if either
or is an infinity and the other a value with equal sign, then return positive infinity.Else if either
or is an infinity and the other a value with opposite sign, then return negative infinity.Else if both
and are zeroes of equal sign, then return positive zero.Else if both
and are zeroes of opposite sign, then return negative zero.Else return the result of multiplying
and , rounded to the nearest representable value.
¶
If either
or is a NaN, then return an element of .Else if both
and are infinities, then return an element of .Else if both
and are zeroes, then return an element of .Else if
is an infinity and a value with equal sign, then return positive infinity.Else if
is an infinity and a value with opposite sign, then return negative infinity.Else if
is an infinity and a value with equal sign, then return positive zero.Else if
is an infinity and a value with opposite sign, then return negative zero.Else if
is a zero and a value with equal sign, then return positive zero.Else if
is a zero and a value with opposite sign, then return negative zero.Else if
is a zero and a value with equal sign, then return positive infinity.Else if
is a zero and a value with opposite sign, then return negative infinity.Else return the result of dividing
by , rounded to the nearest representable value.
¶
If either
or is a NaN, then return an element of .Else if either
or is a negative infinity, then return negative infinity.Else if either
or is a positive infinity, then return the other value.Else if both
and are zeroes of opposite signs, then return negative zero.Else return the smaller value of
and .
¶
If either
or is a NaN, then return an element of .Else if either
or is a positive infinity, then return positive infinity.Else if either
or is a negative infinity, then return the other value.Else if both
and are zeroes of opposite signs, then return positive zero.Else return the larger value of
and .
¶
If
and have the same sign, then return .Else return
with negated sign.
¶
If
is a NaN, then return with positive sign.Else if
is an infinity, then return positive infinity.Else if
is a zero, then return positive zero.Else if
is a positive value, then .Else return
negated.
¶
If
is a NaN, then return with negated sign.Else if
is an infinity, then return that infinity negated.Else if
is a zero, then return that zero negated.Else return
negated.
¶
If
is a NaN, then return an element of .Else if
is negative infinity, then return an element of .Else if
is positive infinity, then return positive infinity.Else if
is a zero, then return that zero.Else if
has a negative sign, then return an element of .Else return the square root of
.
¶
If
is a NaN, then return an element of .Else if
is an infinity, then return .Else if
is a zero, then return .Else if
is smaller than but greater than , then return negative zero.Else return the smallest integral value that is not smaller than
.
¶
If
is a NaN, then return an element of .Else if
is an infinity, then return .Else if
is a zero, then return .Else if
is greater than but smaller than , then return positive zero.Else return the largest integral value that is not larger than
.
¶
If
is a NaN, then return an element of .Else if
is an infinity, then return .Else if
is a zero, then return .Else if
is greater than but smaller than , then return positive zero.Else if
is smaller than but greater than , then return negative zero.Else return the integral value with the same sign as
and the largest magnitude that is not larger than the magnitude of .
¶
If
is a NaN, then return an element of .Else if
is an infinity, then return .Else if
is a zero, then return .Else if
is greater than but smaller than or equal to , then return positive zero.Else if
is smaller than but greater than or equal to , then return negative zero.Else return the integral value that is nearest to
; if two values are equally near, return the even one.
¶
If either
or is a NaN, then return .Else if both
and are zeroes, then return .Else if both
and are the same value, then return .Else return
.
¶
If either
or is a NaN, then return .Else if both
and are zeroes, then return .Else if both
and are the same value, then return .Else return
.
¶
If either
or is a NaN, then return .Else if
and are the same value, then return .Else if
is positive infinity, then return .Else if
is negative infinity, then return .Else if
is positive infinity, then return .Else if
is negative infinity, then return .Else if both
and are zeroes, then return .Else if
is smaller than , then return .Else return
.
¶
If either
or is a NaN, then return .Else if
and are the same value, then return .Else if
is positive infinity, then return .Else if
is negative infinity, then return .Else if
is positive infinity, then return .Else if
is negative infinity, then return .Else if both
and are zeroes, then return .Else if
is larger than , then return .Else return
.
¶
If either
or is a NaN, then return .Else if
and are the same value, then return .Else if
is positive infinity, then return .Else if
is negative infinity, then return .Else if
is positive infinity, then return .Else if
is negative infinity, then return .Else if both
and are zeroes, then return .Else if
is smaller than or equal to , then return .Else return
.
¶
If either
or is a NaN, then return .Else if
and are the same value, then return .Else if
is positive infinity, then return .Else if
is negative infinity, then return .Else if
is positive infinity, then return .Else if
is negative infinity, then return .Else if both
and are zeroes, then return .Else if
is smaller than or equal to , then return .Else return
.
¶
If
is less than then return .Else return
.
¶
If
is less than then return .Else return
.
Conversions¶
¶
Return
.
Note
In the abstract syntax, unsigned extension just reinterprets the same value.
¶
Let
be the signed interpretation of of size .Return the two’s complement of
relative to size .
¶
Return
modulo .
¶
If
is a NaN, then the result is undefined.Else if
is an infinity, then the result is undefined.Else if
is a number and is a value within range of the target type, then return that value.Else the result is undefined.
Note
This operator is partial. It is not defined for NaNs, infinities, or values for which the result is out of range.
¶
If
is a NaN, then the result is undefined.Else if
is an infinity, then the result is undefined.If
is a number and is a value within range of the target type, then return that value.Else the result is undefined.
Note
This operator is partial. It is not defined for NaNs, infinities, or values for which the result is out of range.
¶
If
is a NaN, then return .Else if
is negative infinity, then return .Else if
is positive infinity, then return .Else, return
.
¶
If
is a NaN, then return .Else if
is negative infinity, then return .Else if
is positive infinity, then return .Else, return
.
¶
If
is a canonical NaN, then return an element of (i.e., a canonical NaN of size ).Else if
is a NaN, then return an element of (i.e., any arithmetic NaN of size ).Else, return
.
¶
If
is a canonical NaN, then return an element of (i.e., a canonical NaN of size ).Else if
is a NaN, then return an element of (i.e., any NaN of size ).Else if
is an infinity, then return that infinity.Else if
is a zero, then return that zero.Else, return
.
¶
Return
.
¶
Let
be the signed interpretation of .Return
.
¶
Let
be the bit sequence .Return the constant
for which .
¶
Let
be the signed interpretation of of size .Return
.
¶
Let
be the signed interpretation of of size .Return
.