Floating-Point Ordering¶
Quxlang provides two floating-point comparison families:
| Family | Operations | Semantics |
|---|---|---|
| Value ordering | ==, !=, <, >, <=, >=, <=> |
Strong total order used by Quxlang values |
| IEEE predicates | IEEE_EQUALS, IEEE_NOTEQUALS, IEEE_LESS, IEEE_GREATER |
IEEE equality and ordered relational predicates |
Value ordering¶
The built-in operators compare floating-point values using Quxlang's strong value order. For finite values and infinities, the order is:
All supported NaN encodings are canonicalized to one quiet representation by the language's value semantics. Canonical NaN compares equal to itself and to another canonical NaN:
VAR zero F32 := 0.0;
VAR one F32 := 1.0;
VAR nan F32 := zero / zero;
ASSERT(nan == nan);
ASSERT((nan != nan) == FALSE);
ASSERT((nan <=> nan) == ORDER::EQUAL);
ASSERT(nan > (one / zero));
Negative and positive zero are distinct values:
VAR positive_zero F32 := 0.0;
VAR negative_zero F32 := positive_zero * (positive_zero - 1.0);
ASSERT(negative_zero != positive_zero);
ASSERT(negative_zero < positive_zero);
ASSERT((negative_zero <=> positive_zero) == ORDER::LESS);
<=> returns ORDER::LESS, ORDER::EQUAL, or ORDER::GREATER. The six
Boolean operators agree with that ordering. Arrays and generated structural
comparisons use the same floating-point value order when they compare fields or
elements.
IEEE predicate syntax¶
IEEE_EQUALS(left, right)
IEEE_NOTEQUALS(left, right)
IEEE_LESS(left, right)
IEEE_GREATER(left, right)
Each intrinsic requires exactly two positional floating-point arguments of the
same type and returns BOOL. Named arguments and mixed floating-point types are
not accepted.
| Intrinsic | Result |
|---|---|
IEEE_EQUALS(left, right) |
TRUE when the operands are IEEE equal |
IEEE_NOTEQUALS(left, right) |
TRUE when the operands are unequal or unordered |
IEEE_LESS(left, right) |
TRUE when left is ordered before right |
IEEE_GREATER(left, right) |
TRUE when left is ordered after right |
Special values under IEEE predicates¶
The IEEE predicates treat -0 and +0 as equal:
ASSERT(IEEE_EQUALS(negative_zero, positive_zero));
ASSERT(IEEE_NOTEQUALS(negative_zero, positive_zero) == FALSE);
ASSERT(IEEE_LESS(negative_zero, positive_zero) == FALSE);
ASSERT(IEEE_GREATER(positive_zero, negative_zero) == FALSE);
If either operand is NaN, equality, less-than, and greater-than are FALSE,
while not-equal is TRUE:
ASSERT(IEEE_EQUALS(nan, positive_zero) == FALSE);
ASSERT(IEEE_NOTEQUALS(nan, positive_zero));
ASSERT(IEEE_LESS(nan, positive_zero) == FALSE);
ASSERT(IEEE_GREATER(nan, positive_zero) == FALSE);
This behavior is symmetric in the operand positions. Infinities otherwise participate in IEEE ordered comparison in the usual way.
Comparison family selection¶
The built-in operators apply when a floating-point value requires reflexive equality and strong ordering, including sorting, generated comparison, and serialization. The IEEE predicates apply when signed-zero equivalence or NaN unordered behavior forms part of the numerical algorithm's contract.
Comparison Operators specifies operator dispatch and
ORDER.
Primitive Types and Literals specifies the
supported floating-point types.