Floating-point representation v0.1.0

Source
Signs, exponents, neighbouring values and ulp distances of floating-point values.

CopySign

pub func CopySign(
    magnitude: float64,
    sign: float64
) -> float64

pub func CopySign(
    magnitude: float32,
    sign: float32
) -> float32

magnitude carrying the sign of sign. Works on every value including NaNs and zeros, since it moves one bit and reads no others.

OverloadSummary
pub func CopySign(magnitude: float64, sign: float64) -> float64magnitude carrying the sign of sign.
pub func CopySign(magnitude: float32, sign: float32) -> float32Copies the sign of sign onto magnitude at float32 precision.

Source

Parameters

NameTypeDescription
magnitudefloat64 / float32value supplying every bit except the sign
signfloat64 / float32value supplying the sign bit

Returns: the magnitude of magnitude with the sign of sign

NextAfter

pub func NextAfter(
    from: float64,
    toward: float64
) -> float64

pub func NextAfter(
    from: float32,
    toward: float32
) -> float32

The value adjacent to from in the direction of toward. One representable value in that direction, subnormals and zeros included: stepping down from the smallest positive normal lands in the subnormals rather than jumping to zero, and stepping down from +0.0 gives the smallest negative subnormal rather than -0.0. from equal to toward returns toward, which is what makes the sign of a zero come from the destination. A NaN in either argument gives a NaN.

OverloadSummary
pub func NextAfter(from: float64, toward: float64) -> float64The value adjacent to from in the direction of toward.
pub func NextAfter(from: float32, toward: float32) -> float32Finds the float32 value adjacent to from in the direction of toward.

Source

Parameters

NameTypeDescription
fromfloat64 / float32starting value
towardfloat64 / float32direction selected by another value

Returns: the value adjacent to from toward toward, or toward when they compare equal

NextUp

pub func NextUp(value: float64) -> float64
pub func NextUp(value: float32) -> float32

Finds the next float32 value above value.

OverloadSummary
pub func NextUp(value: float64) -> float64The next representable value above value.
pub func NextUp(value: float32) -> float32Finds the next float32 value above value.

Source

Parameters

NameTypeDescription
valuefloat64 / float32starting value

Returns: the adjacent value toward positive infinity

NextDown

pub func NextDown(value: float64) -> float64
pub func NextDown(value: float32) -> float32

Finds the next float32 value below value.

OverloadSummary
pub func NextDown(value: float64) -> float64The next representable value below value.
pub func NextDown(value: float32) -> float32Finds the next float32 value below value.

Source

Parameters

NameTypeDescription
valuefloat64 / float32starting value

Returns: the adjacent value toward negative infinity

ScaleByPowerOfTwo

pub func ScaleByPowerOfTwo(
    value: float64,
    exponent: int64
) -> float64

pub func ScaleByPowerOfTwo(
    value: float32,
    exponent: int64
) -> float32

value multiplied by two raised to exponent, with one rounding. The obvious spelling - multiplying by a computed power of two - overflows for large exponents and rounds twice when the answer lands in the subnormals. This steps in bounded pieces so neither happens: the result is correctly rounded once, and an exponent far outside the range saturates to an infinity or a zero rather than wrapping the exponent field into a wrong answer.

OverloadSummary
pub func ScaleByPowerOfTwo(value: float64, exponent: int64) -> float64value multiplied by two raised to exponent, with one rounding.
pub func ScaleByPowerOfTwo(value: float32, exponent: int64) -> float32Multiplies value by two raised to exponent at float32 precision.

Source

Parameters

NameTypeDescription
valuefloat64 / float32value to scale
exponentint64binary exponent added to value

Returns: value * 2^exponent, rounded once

ExponentOf

pub func ExponentOf(value: float64) -> int64
pub func ExponentOf(value: float32) -> int64

The exponent of value: the power of two of its most significant bit. A normal value's exponent is such that its magnitude lies in [2^e, 2^(e+1)); a subnormal reports the exponent it would have with unbounded range, so the relationship keeps holding into the subnormals. Zero has no exponent and reports NoExponent, and a NaN or infinity reports IndeterminateExponent; both are values far outside any real exponent, so neither can be mistaken for one.

OverloadSummary
pub func ExponentOf(value: float64) -> int64The exponent of value: the power of two of its most significant bit.
pub func ExponentOf(value: float32) -> int64Extracts the binary exponent of value at float32 precision.

Source

Parameters

NameTypeDescription
valuefloat64 / float32value whose exponent is extracted

Returns: its binary exponent, NoExponent for zero, or IndeterminateExponent for a NaN or infinity

NoExponent

pub const NoExponent: int64 = int64::Min;

What ExponentOf reports for zero, which has no exponent at all.

Source

IndeterminateExponent

pub const IndeterminateExponent: int64 = int64::Max;

What ExponentOf reports for a NaN or an infinity.

Source

Decompose

pub func Decompose(
    value: float64,
    exponent: *var int64
) -> float64

pub func Decompose(
    value: float32,
    exponent: *var int64
) -> float32

Splits value into a fraction in [0.5, 1) and a power of two, so that fraction * 2^exponent == value. The classic decomposition. Zero gives zero with an exponent of zero, and a NaN or infinity is returned unchanged with an exponent of zero - neither has a decomposition, and inventing one would be worse than returning the value itself. The sign stays with the fraction. exponent must be non-null and writable.

OverloadSummary
pub func Decompose(value: float64, exponent: *var int64) -> float64Splits value into a fraction in [0.5, 1) and a power of two, so that fraction * 2^exponent == value.
pub func Decompose(value: float32, exponent: *var int64) -> float32Decomposes value into a float32 fraction and a binary exponent.

Source

Parameters

NameTypeDescription
valuefloat64 / float32value to decompose
exponent*var int64receives the binary exponent

Returns: the signed fraction, normally with magnitude in [0.5, 1)

SplitIntegral

pub func SplitIntegral(
    value: float64,
    integral: *var float64
) -> float64

pub func SplitIntegral(
    value: float32,
    integral: *var float32
) -> float32

Splits value into its integral and fractional parts, both carrying its sign. integral receives the part toward zero and the fractional part is returned, so the two always sum back to value exactly. An infinity puts itself in integral and returns a zero of the same sign; a NaN puts a NaN in both. integral must be non-null and writable.

OverloadSummary
pub func SplitIntegral(value: float64, integral: *var float64) -> float64Splits value into its integral and fractional parts, both carrying its sign.
pub func SplitIntegral(value: float32, integral: *var float32) -> float32Splits value into integral and fractional float32 parts.

Source

Parameters

NameTypeDescription
valuefloat64 / float32value to split
integral*var float64 / *var float32receives the part rounded toward zero

Returns: the signed fractional part

UlpDistance

pub func UlpDistance(
    left: float64,
    right: float64
) -> uint64

pub func UlpDistance(
    left: float32,
    right: float32
) -> uint64

How many representable values lie between left and right. The natural way to state a floating-point error bound: two values are one ulp apart when nothing is representable between them, and a function accurate to half an ulp returns the nearest representable value to the true answer. Counting steps rather than subtracting is what makes the measure meaningful near zero, where the absolute difference between neighbours is vanishingly small, and near the maximum, where it is enormous. Values of opposite sign are counted through zero, with the two zeros treated as one value - the step from the smallest negative subnormal to the smallest positive one is two, not three. A NaN in either argument has no distance and reports the largest uint64, which no real distance can reach.

OverloadSummary
pub func UlpDistance(left: float64, right: float64) -> uint64How many representable values lie between left and right.
pub func UlpDistance(left: float32, right: float32) -> uint64Counts the representable float32 values between left and right.

Source

Parameters

NameTypeDescription
leftfloat64 / float32first value
rightfloat64 / float32second value

Returns: their distance in representable values, or the largest uint64 when either is a NaN