TDLS 0.2.0
Tiny Device-callable Linear Solvers
Loading...
Searching...
No Matches
tdls::StructuralReal< T > Struct Template Reference

Floating-point value stored as an odd integer mantissa and a power-of-two exponent, admissible as a template argument on every compiler supporting class-type non-type template parameters. More...

#include <structural_real.hpp>

Public Member Functions

constexpr StructuralReal () noexcept=default
 The value zero.
 
TDLS_HOST_DEVICE constexpr StructuralReal (const long long m, const int e) noexcept
 Member-wise form, m * 2^e taken as is (no normalization).
 
TDLS_HOST_DEVICE constexpr StructuralReal (const T v) noexcept
 Exact decomposition of a finite value into m * 2^e.
 
TDLS_HOST_DEVICE constexpr bool is_finite () const noexcept
 Whether the stored value is representable (a NaN, an infinity or a mantissa wider than 63 bits given to the constructor is stored as a sentinel instead).
 
TDLS_HOST_DEVICE constexpr operator T () const noexcept
 The stored value, reconstructed exactly.
 

Public Attributes

long long mantissa = 0
 odd integer mantissa, 0 for the value zero
 
int exponent = 0
 power-of-two exponent: value = mantissa * 2^exponent
 

Detailed Description

template<typename T>
struct tdls::StructuralReal< T >

Floating-point value stored as an odd integer mantissa and a power-of-two exponent, admissible as a template argument on every compiler supporting class-type non-type template parameters.

Built implicitly from a value of the scalar type and converted back implicitly, so a designated initializer such as .oot_threshold = 1e-10 needs no wrapper. Only finite values whose odd mantissa fits 63 bits are representable: every float and double, and the long double values built from double literals. A NaN, an infinity or a wider long double mantissa is stored as a sentinel that is_finite() reports, and the solvers reject at compile time.

The member-wise constructor exists for the CUDA toolchain: when nvcc re-emits a translation unit for the host compiler, it spells every class-type template argument as a brace list of its members, nested classes included, so {mantissa, exponent} must be an accepted initialization of this type.

Template Parameters
Tscalar type (float, double or long double)

Constructor & Destructor Documentation

◆ StructuralReal() [1/2]

template<typename T >
TDLS_HOST_DEVICE constexpr tdls::StructuralReal< T >::StructuralReal ( const long long m,
const int e )
inlineconstexprnoexcept

Member-wise form, m * 2^e taken as is (no normalization).

Required by the host-side re-emission of nvcc (see the class documentation); also the natural way to write an exact power of two. Two configurations only name the same solver instantiation when their members are equal, so a non-canonical mantissa (even, or with a different exponent) names a distinct instantiation of the same numerical value.

Parameters
[in]minteger mantissa
[in]epower-of-two exponent

◆ StructuralReal() [2/2]

template<typename T >
TDLS_HOST_DEVICE constexpr tdls::StructuralReal< T >::StructuralReal ( const T v)
inlineconstexprnoexcept

Exact decomposition of a finite value into m * 2^e.

The magnitude is first halved below 2^62 (exact on a normal number), then doubled until integral (exact, and stopped by the sentinel below 2^63), and the integer mantissa is finally reduced to its odd part. Signed zeros both map to (0, 0): thresholds are magnitudes, the sign of zero carries nothing.

Parameters
[in]vthe value to store

Member Function Documentation

◆ is_finite()

template<typename T >
TDLS_HOST_DEVICE constexpr bool tdls::StructuralReal< T >::is_finite ( ) const
inlinenodiscardconstexprnoexcept

Whether the stored value is representable (a NaN, an infinity or a mantissa wider than 63 bits given to the constructor is stored as a sentinel instead).

Returns
true for every representable value, zero included

◆ operator T()

template<typename T >
TDLS_HOST_DEVICE constexpr tdls::StructuralReal< T >::operator T ( ) const
inlinenodiscardconstexprnoexcept

The stored value, reconstructed exactly.

Scaling by a power of two one step at a time is exact at every step: intermediate values carry at least as much precision as the representable end value. The non-finite sentinel converts to zero; the solvers reject it before any conversion.

Returns
mantissa * 2^exponent

The documentation for this struct was generated from the following file: