pic_uint64 Module

Unsigned 64-bit arithmetic for algorithms that are specified in terms of wrapping 64-bit words: hashes, counter-based generators, fixed-point tables.

Why these exist

Fortran has no unsigned integer type, and signed integer overflow is not defined by the standard. The obvious spelling of a wrapping multiply is therefore undefined behaviour, and a build with -ftrapv or -fsanitize=signed-integer-overflow may abort on it. Every routine here splits its operands into limbs so that no intermediate ever leaves the range a signed 64-bit integer can represent.

Bit manipulation goes through ibits, which is defined on the integer bit model and is therefore correct for negative operands: a negative integer(int64) widened through ibits keeps its two’s-complement pattern, which is exactly the unsigned value being modelled. ishft is used only with non-negative (left-shift) counts.

Interpreting the values

A 64-bit unsigned value is carried in an integer(int64) holding its two’s-complement bit pattern, so values at or above 2**63 appear as negative Fortran integers. Fortran’s own < therefore compares them as signed; use u64_less when the unsigned ordering is wanted.


Uses

  • module~~pic_uint64~~UsesGraph module~pic_uint64 pic_uint64 module~pic_types pic_types module~pic_uint64->module~pic_types iso_c_binding iso_c_binding module~pic_types->iso_c_binding iso_fortran_env iso_fortran_env module~pic_types->iso_fortran_env

Used by

  • module~~pic_uint64~~UsedByGraph module~pic_uint64 pic_uint64 module~pic_array_hash pic_array_hash module~pic_array_hash->module~pic_uint64 module~pic_random_dist pic_random_dist module~pic_random_dist->module~pic_uint64 module~pic_rng pic_rng module~pic_random_dist->module~pic_rng module~pic_rng->module~pic_uint64 module~pic_random_dist_real pic_random_dist_real module~pic_random_dist_real->module~pic_rng module~pic_soa pic_soa module~pic_soa->module~pic_array_hash module~pic_soa_particle pic_soa_particle module~pic_soa_particle->module~pic_array_hash module~pic_soa_particle->module~pic_soa

Variables

Type Visibility Attributes Name Initial
integer(kind=int64), private, parameter :: MASK16 = 65535_int64

Low 16-bit mask, used by the limb arithmetic below.

integer(kind=int64), private, parameter :: MASK32 = 4294967295_int64

Low 32-bit mask, used by the limb arithmetic below.


Functions

public pure function u64_add(a, b) result(r)

(a + b) reduced modulo 264, without ever overflowing a signed 64-bit integer. Operands are split into 32-bit halves with ibits, so each half sum stays below 233.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: a
integer(kind=int64), intent(in) :: b

Return Value integer(kind=int64)

public pure function u64_less(a, b) result(r)

.true. when a < b with both operands read as unsigned 64-bit values.

Read more…

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: a
integer(kind=int64), intent(in) :: b

Return Value logical

public pure function u64_mul(a, b) result(r)

(a * b) reduced modulo 2**64, without ever overflowing a signed 64-bit integer.

Read more…

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: a
integer(kind=int64), intent(in) :: b

Return Value integer(kind=int64)

public pure function u64_shr(x, n) result(r)

Logical (zero-filling) right shift of a 64-bit word by n bits, 0 <= n <= 63. Written with ibits rather than ishft(x, -n) or the Fortran 2008 shiftr for the portability reasons given in the module documentation.

Arguments

Type IntentOptional Attributes Name
integer(kind=int64), intent(in) :: x
integer(kind=default_int), intent(in) :: n

Return Value integer(kind=int64)