cryptol-2.11.0: lib/Float.cry
module Float where
primitive type ValidFloat : # -> # -> Prop
/** IEEE-754 floating point numbers. */
primitive type { exponent : #, precision : #}
ValidFloat exponent precision => Float exponent precision : *
/** An abbreviation for common 16-bit floating point numbers. */
type Float16 = Float 5 11
/** An abbreviation for common 32-bit floating point numbers. */
type Float32 = Float 8 24
/** An abbreviation for common 64-bit floating point numbers. */
type Float64 = Float 11 53
/** An abbreviation for common 128-bit floating point numbers. */
type Float128 = Float 15 113
/** An abbreviation for common 256-bit floating point numbers. */
type Float256 = Float 19 237
/* ----------------------------------------------------------------------
* Rounding modes (this should be an enumeration type, when we add these)
*---------------------------------------------------------------------- */
/**
* A 'RoundingMode' is used to specify the precise behavior of some
* floating point primitives.
*
* There are five valid 'RoundingMode' values:
* * roundNearestEven
* * roundNearestAway
* * roundPositive
* * roundNegative
* * roundZero
*/
type RoundingMode = [3]
/** Round toward nearest, ties go to even. */
roundNearestEven, rne : RoundingMode
roundNearestEven = 0
rne = roundNearestEven
/** Round toward nearest, ties away from zero. */
roundNearestAway, rna : RoundingMode
roundNearestAway = 1
rna = roundNearestAway
/** Round toward positive infinity. */
roundPositive, rtp : RoundingMode
roundPositive = 2
rtp = roundPositive
/** Round toward negative infinity. */
roundNegative, rtn : RoundingMode
roundNegative = 3
rtn = roundNegative
/** Round toward zero. */
roundZero, rtz : RoundingMode
roundZero = 4
rtz = roundZero
/* ----------------------------------------------------------------------
* Constants
* ---------------------------------------------------------------------- */
/** Not a number. */
primitive
fpNaN : {e,p} ValidFloat e p => Float e p
/** Positive infinity. */
primitive
fpPosInf : {e,p} ValidFloat e p => Float e p
/** Negative infinity. */
fpNegInf : {e,p} ValidFloat e p => Float e p
fpNegInf = - fpPosInf
/** Positive zero. */
fpPosZero : {e,p} ValidFloat e p => Float e p
fpPosZero = zero
/** Negative zero. */
fpNegZero : {e,p} ValidFloat e p => Float e p
fpNegZero = - fpPosZero
// Binary representations
/** A floating point number using the exact bit pattern,
in IEEE interchange format with layout:
(sign : [1]) # (biased_exponent : [e]) # (significand : [p-1])
*/
primitive
fpFromBits : {e,p} ValidFloat e p => [e + p] -> Float e p
/** Export a floating point number in IEEE interchange format with layout:
(sign : [1]) # (biased_exponent : [e]) # (significand : [p-1])
NaN is represented as:
* positive: sign == 0
* quiet with no info: significand == 0b1 # 0
*/
primitive
fpToBits : {e,p} ValidFloat e p => Float e p -> [e + p]
/* ----------------------------------------------------------------------
* Predicates
* ----------------------------------------------------------------------
*/
// Operations in `Cmp` use IEEE reasoning.
/** Check if two floating point numbers are representationally the same.
In particular, the following hold:
* NaN =.= NaN
* ~ (pfNegZero =.= fpPosZero)
*/
primitive
(=.=) : {e,p} ValidFloat e p => Float e p -> Float e p -> Bool
infix 20 =.=
/** Test if this value is not-a-number (NaN). */
primitive fpIsNaN : {e,p} ValidFloat e p => Float e p -> Bool
/** Test if this value is positive or negative infinity. */
primitive fpIsInf : {e,p} ValidFloat e p => Float e p -> Bool
/** Test if this value is positive or negative zero. */
primitive fpIsZero : {e,p} ValidFloat e p => Float e p -> Bool
/** Test if this value is negative. */
primitive fpIsNeg : {e,p} ValidFloat e p => Float e p -> Bool
/** Test if this value is normal (not NaN, not infinite, not zero, and not subnormal). */
primitive fpIsNormal : {e,p} ValidFloat e p => Float e p -> Bool
/**
* Test if this value is subnormal. Subnormal values are nonzero
* values with magnitudes smaller than can be represented with the
* normal implicit leading bit convention.
*/
primitive fpIsSubnormal : {e,p} ValidFloat e p => Float e p -> Bool
/* Returns true for numbers that are not an infinity or NaN. */
fpIsFinite : {e,p} ValidFloat e p => Float e p -> Bool
fpIsFinite f = ~ (fpIsNaN f \/ fpIsInf f )
/* ----------------------------------------------------------------------
* Arithmetic
* ---------------------------------------------------------------------- */
/** Add floating point numbers using the given rounding mode. */
primitive
fpAdd : {e,p} ValidFloat e p =>
RoundingMode -> Float e p -> Float e p -> Float e p
/** Subtract floating point numbers using the given rounding mode. */
primitive
fpSub : {e,p} ValidFloat e p =>
RoundingMode -> Float e p -> Float e p -> Float e p
/** Multiply floating point numbers using the given rounding mode. */
primitive
fpMul : {e,p} ValidFloat e p =>
RoundingMode -> Float e p -> Float e p -> Float e p
/** Divide floating point numbers using the given rounding mode. */
primitive
fpDiv : {e,p} ValidFloat e p =>
RoundingMode -> Float e p -> Float e p -> Float e p
/**
* Fused-multiply-add. 'fpFMA r x y z' computes the value '(x*y)+z',
* rounding the result according to mode 'r' only after performing both
* operations.
*/
primitive
fpFMA : {e,p} ValidFloat e p =>
RoundingMode -> Float e p -> Float e p -> Float e p -> Float e p
/**
* Absolute value of a floating-point value.
*/
primitive
fpAbs : {e,p} ValidFloat e p =>
Float e p -> Float e p
/**
* Square root of a floating-point value. The square root of
* a negative value yiels NaN, except that the sqaure root of
* '-0.0' is '-0.0'.
*/
primitive
fpSqrt : {e,p} ValidFloat e p =>
RoundingMode -> Float e p -> Float e p
/* ------------------------------------------------------------ *
* Rationals *
* ------------------------------------------------------------ */
/** Convert a floating point number to a rational.
It is an error to use this with infinity or NaN **/
primitive
fpToRational : {e,p} ValidFloat e p =>
Float e p -> Rational
/** Convert a rational to a floating point number, using the
given rounding mode, if the number cannot be represented exactly. */
primitive
fpFromRational : {e,p} ValidFloat e p =>
RoundingMode -> Rational -> Float e p