Control of the precision f_precisions¶
The f_precisions module defines the portable Futile kind policy and
the public sentinel helpers used by host codes.
Description
Defines the portable Futile kind policy, undefined sentinels, precision conversion helpers, and low-level address inquiry helpers. Host codes should use these names instead of compiler-specific kind constants when exposing Futile-compatible public APIs.
Public items are grouped into four families:
ABI kind parameters such as f_integer, f_double, and f_byte.
Semantic kind parameters such as f_quadruple, f_address, and f_size_t.
Undefined sentinel constants and generic sentinel helper interfaces.
Low-level portability helpers such as f_loc, f_sizeof, and f_simplify.
Quick access
- Types:
- Variables:
f_0,f_1,f_address,f_backslash,f_byte,f_cr,f_double,f_f,f_int8,f_integer,f_logical,f_long,f_long_double,f_quadruple,f_short,f_simple,f_size_t,f_t,undefined_f_double,undefined_f_int8,undefined_f_integer,undefined_f_long,undefined_f_long_double,undefined_f_short,undefined_f_simple- Routines:
f_is_defined(),f_is_undefined(),f_undefine(),f_undefined()
ABI kind parameters
Futile public APIs should use these names when exposing data whose binary representation must be stable across Fortran/C boundaries or across BigDFT components.
- f_precisions/f_int8 [integer,public/parameter/default=c_int8_t]¶
C-compatible signed 8-bit integer kind.
- f_precisions/f_short [integer,public/parameter/default=c_int16_t]¶
C-compatible signed 16-bit integer kind.
- f_precisions/f_integer [integer,public/parameter/default=c_int32_t]¶
C-compatible signed 32-bit integer kind; canonical Futile integer.
- f_precisions/f_long [integer,public/parameter/default=c_int64_t]¶
C-compatible signed 64-bit integer kind.
- f_precisions/f_simple [integer,public/parameter/default=c_float]¶
C float-compatible real kind.
- f_precisions/f_double [integer,public/parameter/default=c_double]¶
C double-compatible real kind; canonical Futile real.
- f_precisions/f_long_double [integer,public/parameter/default=c_long_double]¶
C long double-compatible real kind when supported.
- f_precisions/f_byte [integer,public/parameter/default=c_bool]¶
C bool-compatible logical kind; not an integer byte kind.
- f_precisions/f_logical [integer,public/parameter/default=kind(.false.)]¶
Semantic kind parameters
These names describe host-code intent and should not be used to define required overload families without first checking that the compiler and platform support the requested representation.
- f_precisions/f_quadruple [integer,public/parameter/default=selected_real_kind(33,4931)]¶
- f_precisions/f_address [integer,public/parameter/default=c_intptr_t]¶
Integer kind large enough to store a C address.
- f_precisions/f_size_t [integer,public/parameter/default=c_size_t]¶
Integer kind compatible with C size_t values.
Preferred undefined sentinel constants
These constants define the public sentinel values used by f_undefined, f_undefine, and f_is_undefined. Integer sentinels use the lowest representable value for the corresponding Futile kind. Real sentinels use quiet NaN bit patterns where portable initialization expressions are available.
- f_precisions/undefined_f_int8 [integer,public/parameter/default=-huge(0_f_int8)]¶
- f_precisions/undefined_f_short [integer,public/parameter/default=-huge(0_f_short)]¶
- f_precisions/undefined_f_integer [integer,public/parameter/default=-huge(0_f_integer)]¶
- f_precisions/undefined_f_long [integer,public/parameter/default=-huge(0_f_long)]¶
- f_precisions/undefined_f_simple [real,public/parameter/default=transfer(f_quiet_nan_simple_words,0.0_f_simple)]¶
- f_precisions/undefined_f_double [real,public/parameter/default=transfer(f_quiet_nan_double_words,0.0_f_double)]¶
- f_precisions/undefined_f_long_double [real,public/parameter/default=-huge(0.0_f_long_double)]¶
Assignment token constants
These parameter values are used by the assignment generic to initialize common scalar values without repeating literal constants at call sites.
- f_precisions/f_0 [f_parameter,public/parameter/default=f_parameter(c_0)]¶
- f_precisions/f_1 [f_parameter,public/parameter/default=f_parameter(c_1)]¶
C-compatible logical constants
Use these constants only where the ABI requires logical(f_byte); use ordinary .true. and .false. for default Fortran logic.
- f_precisions/f_t [logical,public/parameter/default=.true._f_byte]¶
C-compatible true value.
- f_precisions/f_f [logical,public/parameter/default=.false._f_byte]¶
C-compatible false value.
Types
- type f_precisions/f_parameter¶
- Type fields:
% val [character(len=num_size)]
Variables
- f_precisions/f_backslash [character(len=*),public/parameter/default=char(92)]¶
- f_precisions/f_cr [character(len=*),public/parameter/default=char(13)//char(10)]¶
Subroutines and functions
- interface f_precisions/assignment(=)(val, par)¶
- Parameters:
val [real, integer, character(len=*), out]
par [f_parameter, in]
- interface f_precisions/f_undefined(one)¶
Return an undefined sentinel value with the same intrinsic kind as the mold argument.
This is the constructor-like entry point of the undefined sentinel API. Preferred usage is to obtain a sentinel with x = f_undefined(x), assign one in place with call f_undefine(x), and test values with f_is_undefined(x) or f_is_defined(x).
Do not compare sentinel values with == or /= in client code. The real and complex sentinels may use quiet NaN bit patterns, for which ordinary numerical comparison is neither portable nor semantically correct. Logical kinds are intentionally unsupported because there is no portable sentinel value distinct from true and false.
- Parameters:
one [complex, in]
- interface f_precisions/f_undefine(value)¶
Assign the undefined sentinel to a scalar variable in place.
This is the in-place form of f_undefined: after the call, the scalar value carries the Futile undefined representation for its intrinsic kind. Test the result with f_is_undefined or f_is_defined rather than with direct equality comparisons.
- Parameters:
value [complex, out]
- interface f_precisions/f_is_undefined(value)¶
Test whether a scalar value has the Futile undefined sentinel representation.
This predicate is the portable way to recognize undefined values produced by f_undefined or f_undefine, including real and complex sentinels represented with quiet NaN bit patterns.
- Parameters:
value [complex, in]
- interface f_precisions/f_is_defined(value)¶
Test whether a scalar value is different from the Futile undefined sentinel representation.
This is the logical complement of f_is_undefined and is preferred over direct comparisons with the sentinel constants, so generic code remains safe when the intrinsic kind changes.
- Parameters:
value [complex, in]
The page intentionally relies on the default public-only behavior of
f:automodule. Public generic interfaces such as f_sizeof(),
f_undefined(), f_undefine(), f_is_undefined(), and
f_is_defined() are rendered as interface entries. Their private
implementation procedures are not part of the public documentation contract.
Address inquiry¶
- function f_precisions/f_loc(x)¶
Return the memory address associated with a scalar object as an
integer(f_address)value. This is Futile’s portable wrapper around the non-standardlocfunctionality traditionally provided by GNU Fortran.Use this routine only for low-level interoperability or storage-layout inquiries. The argument may be an intrinsic scalar, a derived-type object, or a procedure target, but it must not be a nullified pointer.
- Parameters:
x [in] :: scalar object whose address is queried.
- Return:
f_loc [integer(f_address)] :: address of
x.
CI-covered example:
subroutine example_f_loc() integer(f_address) :: address real(f_double), target :: value value = 1.0_f_double address = f_loc(value) call require(address /= 0_f_address, 'f_loc returned a null address') end subroutine example_f_loc
Precision helpers¶
The helper APIs below are rendered from the Fortran source with constrained
f:automodule directives. The surrounding prose and examples stay close to
the page, while signatures, argument lists, return values, and interface
membership remain source-driven.
Storage-size inquiry¶
Subroutines and functions
- interface f_precisions/f_sizeof(av)¶
Return the storage size in bytes of a scalar Futile intrinsic kind. This generic is implemented by private kind-specific procedures and is exposed as the public API entry.
subroutine example_f_sizeof() real(f_double) :: x integer(f_integer) :: i call require(f_sizeof(x) > 0, 'f_sizeof failed for real(f_double)') call require(f_sizeof(i) > 0, 'f_sizeof failed for integer(f_integer)') end subroutine example_f_sizeof
- Parameters:
av [real, integer, logical, in]
The public API is the generic interface above. It returns the storage size in bytes of a scalar Futile intrinsic value and is implemented by private kind-specific procedures.
Use it for low-level portability checks, binary layout diagnostics, and code that must reason about the storage occupied by Futile ABI kinds.
Precision reduction¶
Subroutines and functions
- function f_precisions/f_simplify(d)¶
Convert a double-precision value to simple precision while saturating values outside the simple-precision representable range.
subroutine example_f_simplify() real(f_double) :: x real(f_simple) :: y x = 1.0_f_double / 3.0_f_double y = f_simplify(x) call require(abs(real(y, f_double) - x) < 1.0e-6_f_double, & 'f_simplify changed a representable value too much') end subroutine example_f_simplify
- Parameters:
d [real, in] :: Input double-precision value.
- Return:
r [real] :: Simple-precision value after range protection.
Use this helper when reducing precision intentionally, so the conversion policy is explicit at the call site. Values outside the simple-precision range are saturated instead of relying on compiler-dependent overflow or underflow behavior.
Tolerance-based greater-than comparison¶
Subroutines and functions
- function f_precisions/gt_with_tol(a, b[, tol])¶
Compare two double-precision values with an optional tolerance.
subroutine example_gt_with_tol() real(f_double) :: a a = 1.0_f_double call require(gt_with_tol(a + 2.0_f_double * epsilon(a), a), & 'gt_with_tol did not detect a significant positive difference') call require(.not. gt_with_tol(a + 0.5_f_double * epsilon(a), a), & 'gt_with_tol treated a roundoff-level difference as significant') end subroutine example_gt_with_tol
- Parameters:
a [real, in]
b [real, in] :: Values to compare.
- Options:
tol [real, in,] :: Comparison tolerance; defaults to machine epsilon.
- Return:
yes [logical] :: True when a is larger than b by more than the tolerance.
Use this elemental helper when a strict greater-than comparison should ignore roundoff-level differences.
Tolerance-based equality comparison¶
Subroutines and functions
- function f_precisions/eq_with_tol(a, b[, tol])¶
Compare two double-precision values for equality with an optional tolerance.
subroutine example_eq_with_tol() real(f_double) :: a a = 1.0_f_double call require(eq_with_tol(a + 0.5_f_double * epsilon(a), a), & 'eq_with_tol rejected a roundoff-level difference') call require(.not. eq_with_tol(a + 2.0_f_double * epsilon(a), a), & 'eq_with_tol accepted a significant difference') end subroutine example_eq_with_tol
- Parameters:
a [real, in]
b [real, in] :: Values to compare.
- Options:
tol [real, in,] :: Comparison tolerance; defaults to machine epsilon.
- Return:
yes [logical] :: True when the absolute difference is smaller than the tolerance.
Use this elemental helper when equality should be interpreted with a numerical tolerance instead of exact bitwise equality.
Documentation coverage¶
The CI documentation contract for this page checks two complementary notions of coverage:
symbol coverageEvery expected public
f_precisionsentry must appear in the rendered HTML page. This catches missing public constants, interfaces, and helper functions when the parser or the source changes.topic coverageRequired explanatory topics must also appear in the rendered page. For this module the required topics cover ABI kinds, semantic kinds, undefined sentinels, address inquiry, storage-size inquiry, precision conversion, and tolerance-based comparisons.
example coveragePublic helpers should include examples with
fortranliteraldirectives taken from executable code undertests/. The same code is compiled and run by CI, so the rendered documentation cannot silently drift away from tested API behavior. For parsed helpers and interfaces, the directive should live in the Fortran source comment next to the public API. Manual objects such as the externalf_locwrapper may keep the directive in the page until sphinxfortran can render them directly from source. If a public function has no runnable example, the page and source comment should explain why and the coverage check should make that exception explicit.
This is intentionally stricter than checking that Sphinx exits successfully: a
page can build while still being unhelpful to users. The coverage check lives in
doc/check_sphinxfortran_public_api.py and should be extended whenever a new
public API family is added.