Skip to content

stringifor_numbers ​

StringiFor, conversions between decimal and binary reals on 64 bit integers (internal module, not re-exported).

Fortran has no unsigned integer, and a signed overflow is not allowed: the 64 bit words are handled as bit patterns, and the arithmetic on them goes through 32 bit limbs that cannot overflow.

Source: src/lib/stringifor_numbers.F90

Dependencies

Contents ​

Variables ​

NameTypeAttributesDescription
LOW32integer(kind=I8P)parameterThe low 32 bits.

Subroutines ​

shortest_digits ​

Return the shortest decimal digits * 10**exponent that reads back as the binary float, the closest of them if more than one (Schubfach: Giulietti, The Schubfach way to render doubles, 2020). Finite and not zero; no trailing zeros.

The float is given by its fields, so one kernel serves R4P and R8P: every step only relies on the 128 bits of the power.

Attributes: elemental

fortran
subroutine shortest_digits(fraction, biased, mantissa_bits, digits, exponent)

Arguments

NameTypeIntentAttributesDescription
fractioninteger(kind=I8P)inStored mantissa.
biasedintegerinBiased exponent.
mantissa_bitsintegerinBits of the stored mantissa.
digitsinteger(kind=I8P)outDecimal digits.
exponentintegeroutDecimal exponent.

Call graph

strip_zeros ​

Move the trailing zeros of the digits to the exponent.

Attributes: elemental

fortran
subroutine strip_zeros(digits, exponent)

Arguments

NameTypeIntentAttributesDescription
digitsinteger(kind=I8P)inoutDecimal digits, not zero.
exponentintegerinoutDecimal exponent.

Call graph

add ​

Add two words as unsigned integers.

Attributes: elemental

fortran
subroutine add(a, b, sum, carry)

Arguments

NameTypeIntentAttributesDescription
ainteger(kind=I8P)inFirst word.
binteger(kind=I8P)inSecond word.
suminteger(kind=I8P)outLow 64 bits of the sum.
carryinteger(kind=I8P)outCarry, 0 or 1.

Call graph

multiply ​

Multiply two words as unsigned integers, 64 x 64 = 128 bits.

Attributes: elemental

fortran
subroutine multiply(a, b, high, low)

Arguments

NameTypeIntentAttributesDescription
ainteger(kind=I8P)inFirst word.
binteger(kind=I8P)inSecond word.
highinteger(kind=I8P)outHigh word.
lowinteger(kind=I8P)outLow word.

Call graph

multiply32 ​

Multiply two 32 bit limbs: a product of a limb and 16 bits fits in a signed word, a product of two limbs may not.

Attributes: elemental

fortran
subroutine multiply32(a, b, high, low)

Arguments

NameTypeIntentAttributesDescription
ainteger(kind=I8P)inFirst limb.
binteger(kind=I8P)inSecond limb.
highinteger(kind=I8P)outHigh limb.
lowinteger(kind=I8P)outLow limb.

Call graph

Functions ​

decimal_to_r8 ​

Return the real nearest to mantissa * 10**exponent, ties to even (Eisel-Lemire). Mantissa not negative.

Attributes: elemental

Returns: real(kind=R8P)

fortran
function decimal_to_r8(mantissa, exponent) result(number)

Arguments

NameTypeIntentAttributesDescription
mantissainteger(kind=I8P)inDigits, as an integer.
exponentintegerinDecimal exponent.

Call graph

decimal_to_r4 ​

Return the real nearest to mantissa * 10**exponent, ties to even (Eisel-Lemire). Mantissa not negative.

Attributes: elemental

Returns: real(kind=R4P)

fortran
function decimal_to_r4(mantissa, exponent) result(number)

Arguments

NameTypeIntentAttributesDescription
mantissainteger(kind=I8P)inDigits, as an integer.
exponentintegerinDecimal exponent.

Call graph

floor_shift ​

Return floor(value / 2**bits): nvfortran has no SHIFTA, and a right shift of a negative number needs the floor.

Attributes: elemental

Returns: integer

fortran
function floor_shift(value, bits) result(shifted)

Arguments

NameTypeIntentAttributesDescription
valueintegerinThe value.
bitsintegerinThe bits of the shift.

Call graph

BIAS_BITS ​

Return the bits of the exponent field of a format.

Attributes: elemental

Returns: integer

fortran
function BIAS_BITS(mantissa_bits) result(bits)

Arguments

NameTypeIntentAttributesDescription
mantissa_bitsintegerinBits of the stored mantissa.

Call graph

round_to_odd ​

Return the high word of g * cp (g of 128 bits) with its lowest bit set if any bit below is set.

Attributes: elemental

Returns: integer(kind=I8P)

fortran
function round_to_odd(g_high, g_low, cp) result(rounded)

Arguments

NameTypeIntentAttributesDescription
g_highinteger(kind=I8P)inHigh word of g.
g_lowinteger(kind=I8P)inLow word of g.
cpinteger(kind=I8P)inThe multiplier.

Call graph

eisel_lemire ​

Return the bits of the positive binary float nearest to digits * 10**q, of the format with those parameters.

The 128 bits of the table are enough for every 64 bit digits, so this has no fallback (Mushtak, Lemire, Fast Number Parsing Without Fallback, 2023); the oracle checks it against exact arithmetic.

Attributes: elemental

Returns: integer(kind=I8P)

fortran
function eisel_lemire(digits, q, mantissa_bits, bias, infinity, even_min, even_max) result(bits)

Arguments

NameTypeIntentAttributesDescription
digitsinteger(kind=I8P)inDecimal digits, not zero.
qintegerinDecimal exponent, in the range of the table.
mantissa_bitsintegerinBits of the stored mantissa.
biasintegerinExponent bias.
infinityintegerinBiased exponent of the infinity.
even_minintegerinLowest q where a product can be an exact tie.
even_maxintegerinHighest q where a product can be an exact tie.

Call graph