rocq/theories/Ieee.v
IEEE 754 arithmetic with integers only, transcribed from ieee.pl: binary32 (s), binary64 (d) and the x87 80-bit extended format (x), rounding to nearest, ties to even.
Operands and results are unsigned bit patterns, as in interp.pl, never host floats. A finite value is an exact rational, and round_ratio is the one place where rounding happens, gradual underflow and overflow included. The decimal parser and printer (ieee_parse/3, ieee_decimal/3) are the frontend's and stay out.
Parts
Formats
| | | FmtS | ||
| | | FmtD | ||
| | | FmtX |
As format(K, Fraction, _, _): the bits of the fraction of the format k, without the integer bit, which only x stores explicitly.
As format(K, _, Exponent, _): the bits of the exponent field.
As format(K, _, _, Bias): the exponent bias, the stored exponent of 1.0.
As integer_bit(K, Bits): the explicit integer bit, if any; the exponent starts above it.
As exponent_shift(K, Sh): the position of the exponent field's lowest bit, above the fraction and the integer bit.
Decoding
What a bit pattern is, decode/4's T.
| | | Inf | an infinity | |
| | | NaN | not a number | |
| | | Finite | n p : Z | the finite value n × 2^p |
As decode(K, B, S, T): the sign S and the value T of the pattern b in the format k. A zero exponent is a subnormal (or zero), whose significand is all the bits below the exponent.
As sign_bits(K, S, B): the pattern with only the sign s, 0 or 1; also the zero of that sign.
As infinity(K, S, B): the infinity of sign s (x's has its integer bit set).
As quiet(K, A, B): the pattern a with the top fraction bit set, which makes a NaN quiet.
As invalid(K, B): the default NaN, a quiet negative one, the result of an invalid operation.
Rounding
As ilog(N, L): floor(log2(N)) for a positive n, and -1 for 0.
As scale(N, D, E, A, B): the ratio A/B that is n/d × 2^e, both parts integers.
As round_even(N, D, Q): the positive quotient N/D rounded to nearest, a tie to the even neighbour. N and D are positive, so Prolog's // is Z.div (Z.quot is the same here, but its extraction divides bit by bit, which takes minutes on the 16000-bit ratios of an x denormal).
As round_ratio(K, S, N, D, B): the pattern of format k and sign s nearest n/d, for n ≥ 0, ties to even. The exponent is the one of n/d, raised to the least normal one (so small values round as subnormals), and an overflow is an infinity.
As finite_ratio(T, A, B): the finite value n × 2^p as a ratio of non-negative integers.
As signed_ratio(S, T, N, D): the same ratio, with the sign s applied to its numerator.
Integers
As ieee_from_int(K, N, B): the pattern of format k nearest the integer n.
As ieee_to_int(K, B, N): the finite pattern b truncated toward zero; none for an infinity or NaN. The ratio's parts are non-negative, so // is Z.div here too.
Arithmetic
As ieee_neg(K, A, B): the pattern a with its sign bit flipped, NaNs included.
As x87_nan(A, B, R): the result of an x op on two NaNs a and b, by the x87's rule (Intel SDM vol. 1, 4.8.3.5): a quiet one wins over a signaling one, else the one with the larger significand, else the first, and the winner is quieted.
The four arithmetic operations: add, subtract, multiply, divide.
| | | FAdd | ||
| | | FSub | ||
| | | FMul | ||
| | | FDiv |
Whether a decoded value t is a zero, of either sign.
Whether a decoded value t is an infinity.
As binary(add, K, SA, TA, SB, TB, R): the sum of two non-NaN values, ta of sign sa and tb of sign sb. An exact zero sum is negative only when both operands are; infinities of opposite signs give the default NaN.
As binary(Op, K, SA, TA, SB, TB, R): the op o on two non-NaN values. The invalid cases, zero times infinity, zero over zero and infinity over infinity, give the default NaN invalid.
As ieee_convert(From, To, A, B): the pattern a of format from in the format to, rounded to nearest; a NaN keeps as much of its payload as fits, aligned at the top, and is quieted.
As ieee_sqrt(K, A, B): the square root of the pattern a of format k, rounded to nearest, ties to even, as sqrtss, sqrtsd and fsqrt compute it. A NaN is quieted; +0, -0 and +inf are themselves; any other negative number, -inf included, gives the default NaN. For a finite n × 2^p, p made even, the root of n × 4^g with g = f + 5 has at least g bits, two more than rounding needs, and an inexact root lying strictly between q and q + 1 rounds as q + 1/2 does. Z.sqrt is isqrt/2, the floor of the root.
Comparison
A float comparison's condition (condition/2): equal, not equal, the four orders, ordered (neither is a NaN) and unordered (one is).
| | | FEq | ||
| | | FNe | ||
| | | FLt | ||
| | | FLe | ||
| | | FGt | ||
| | | FGe | ||
| | | FOrd | ||
| | | FUnord |
How two values compare: the standard order, or unordered when one is a NaN.
| | | Below | ||
| | | Same | ||
| | | Above | ||
| | | Unordered |
The order of a Rocq comparison.
As condition(Cond, Order): whether the condition c holds of two values that compare as o.
As ieee_compare(K, Cond, A, B, R): 1 when a c b holds of the patterns a and b of format k, else 0. With a NaN only ne and uo hold; the two zeros are equal.