Library: better short-hand name for long double

As with all those C++ base types, unfortunately they are giving you
only rough size guarantees. For Lumiera, I defined short hand names
some time ago, notably because the explicit long X and short X qualifiers
do not work with ''constructor syntax'' for direct conversions.

But I choose the name `f128` at that time -- which might raise ill-guided
expectations, since the `long double` is not that long on relevant linux 64bit
platforms; it can just hold 64bit of mantissa at least however.

As replacement, I'll use `lflo` now, because it has also 4 letters,
looks somewhat weird (and thus catches attention) and points into the
right direction. I considered `lfloat` as alternative, but that looks
too much like `float`, visually...
This commit is contained in:
Fischlurch 2026-09-21 01:05:53 +02:00
parent e3a8ce1b5e
commit 4f8a8e8042
10 changed files with 20 additions and 17 deletions

View file

@ -363,11 +363,11 @@ namespace util {
string showDecimal (double val) noexcept { return showFloatingPoint (val, PRECISION_DECIMAL<double>); } string showDecimal (double val) noexcept { return showFloatingPoint (val, PRECISION_DECIMAL<double>); }
string showDecimal (float val) noexcept { return showFloatingPoint (val, PRECISION_DECIMAL<float>); } string showDecimal (float val) noexcept { return showFloatingPoint (val, PRECISION_DECIMAL<float>); }
string showDecimal (f128 val) noexcept { return showFloatingPoint (val, PRECISION_DECIMAL<f128>); } string showDecimal (lflo val) noexcept { return showFloatingPoint (val, PRECISION_DECIMAL<lflo>); }
string showComplete (double val) noexcept { return showFloatingPoint (val, PRECISION_COMPLETE<double>); } string showComplete (double val) noexcept { return showFloatingPoint (val, PRECISION_COMPLETE<double>); }
string showComplete (float val) noexcept { return showFloatingPoint (val, PRECISION_COMPLETE<float>); } string showComplete (float val) noexcept { return showFloatingPoint (val, PRECISION_COMPLETE<float>); }
string showComplete (f128 val) noexcept { return showFloatingPoint (val, PRECISION_COMPLETE<f128>); } string showComplete (lflo val) noexcept { return showFloatingPoint (val, PRECISION_COMPLETE<lflo>); }
string string

View file

@ -93,10 +93,10 @@ namespace util {
std::string showDecimal (double) noexcept; std::string showDecimal (double) noexcept;
std::string showDecimal (float) noexcept; std::string showDecimal (float) noexcept;
std::string showDecimal (f128) noexcept; std::string showDecimal (lflo) noexcept;
std::string showComplete (double)noexcept; std::string showComplete (double)noexcept;
std::string showComplete (float) noexcept; std::string showComplete (float) noexcept;
std::string showComplete (f128) noexcept; std::string showComplete (lflo) noexcept;

View file

@ -32,8 +32,8 @@ using llong = long long int;
using ullong = unsigned long long int; using ullong = unsigned long long int;
using ushort = unsigned short int; using ushort = unsigned short int;
using f128 = long double; using lflo = long double;
static_assert(10 <= sizeof(f128)); static_assert(10 <= sizeof(lflo));
const uint LIFE_AND_UNIVERSE_4EVER = 42; const uint LIFE_AND_UNIVERSE_4EVER = 42;

View file

@ -456,12 +456,12 @@ namespace util {
/** show maximum reproducible decimal representation */ /** show maximum reproducible decimal representation */
std::string showDecimal (double) noexcept; std::string showDecimal (double) noexcept;
std::string showDecimal (float) noexcept; std::string showDecimal (float) noexcept;
std::string showDecimal (f128) noexcept; std::string showDecimal (lflo) noexcept;
/** show enough decimal digits to represent every distinct value */ /** show enough decimal digits to represent every distinct value */
std::string showComplete (double) noexcept; std::string showComplete (double) noexcept;
std::string showComplete (float) noexcept; std::string showComplete (float) noexcept;
std::string showComplete (f128) noexcept; std::string showComplete (lflo) noexcept;
std::string showSize (size_t) noexcept; std::string showSize (size_t) noexcept;

View file

@ -180,11 +180,14 @@ _Pragma("GCC diagnostic pop")
if constexpr (8 > sizeof(U)) if constexpr (8 > sizeof(U))
return std::type_identity<int64_t>{}; return std::type_identity<int64_t>{};
else else
return std::type_identity<f128>{}; return std::type_identity<lflo>{};
// no standard integral type can hold uint64_t's full range signed. // no standard integral type can hold uint64_t's full range signed.
// Expand to long double, which can hold 64bit without precision loss // Expand to long double, which can hold 64bit without precision loss
} }
} }
static_assert (64 <= std::numeric_limits<lflo>::digits
,"long double type can not represent uint64_t exactly");
} }
/** /**

View file

@ -122,12 +122,12 @@ namespace util {
u = 0!=u? u:1; u = 0!=u? u:1;
auto [d,r] = util::iDiv (num, den); auto [d,r] = util::iDiv (num, den);
// round to smallest integer fraction, to shake off "number dust" // round to smallest integer fraction, to shake off "number dust"
f128 const ROUND_ULP = 1 + 1/(f128(std::numeric_limits<int64_t>::max()) * 2); lflo const ROUND_ULP = 1 + 1/(lflo(std::numeric_limits<int64_t>::max()) * 2);
// construct approximation quantised to 1/u // construct approximation quantised to 1/u
f128 frac = f128(r) / den; lflo frac = lflo(r) / den;
int64_t res = d*u + int64_t(frac*u * ROUND_ULP); int64_t res = d*u + int64_t(frac*u * ROUND_ULP);
ENSURE (abs (f128(res)/u - rational_cast<f128>(Rat{num,den})) <= 1.0/abs(u) ENSURE (abs (lflo(res)/u - rational_cast<lflo>(Rat{num,den})) <= 1.0/abs(u)
,"Requantisation error exceeded num=%li / den=%li -> res=%li / quant=%li" ,"Requantisation error exceeded num=%li / den=%li -> res=%li / quant=%li"
, num, den, res, u); , num, den, res, u);
return res; return res;

View file

@ -76,7 +76,7 @@ namespace test {
verifyFloatTypes<float>(); verifyFloatTypes<float>();
verifyFloatTypes<double>(); verifyFloatTypes<double>();
verifyFloatTypes<f128>(); verifyFloatTypes<lflo>();
} }

View file

@ -134,7 +134,7 @@ namespace test{
CHECK ( 15 == angleScale.conform(65535)); CHECK ( 15 == angleScale.conform(65535));
Scale<f128> tinyScale = {.minVal=-f128(1)/100, .maxVal=f128(1)/100}; Scale<lflo> tinyScale = {.minVal=-lflo(1)/100, .maxVal=lflo(1)/100};
tinyScale.cyclicLim = util::limit_cyclicWrap(*tinyScale.maxVal - *tinyScale.minVal); tinyScale.cyclicLim = util::limit_cyclicWrap(*tinyScale.maxVal - *tinyScale.minVal);
CHECK (1e16 < tinyScale.cyclicLim); CHECK (1e16 < tinyScale.cyclicLim);
CHECK (tinyScale.isValid()); CHECK (tinyScale.isValid());

View file

@ -224,7 +224,7 @@ namespace test{
CHECK (format4Csv(double(1) / 3) == "0.333333333333333"_expect ); CHECK (format4Csv(double(1) / 3) == "0.333333333333333"_expect );
CHECK (format4Csv(float(1) / 3) == "0.333333"_expect ); CHECK (format4Csv(float(1) / 3) == "0.333333"_expect );
CHECK (format4Csv(f128(1) / 3) == "0.333333333333333333"_expect); CHECK (format4Csv(lflo(1) / 3) == "0.333333333333333333"_expect);
CHECK (format4Csv(bool(1)) == "true"_expect ); CHECK (format4Csv(bool(1)) == "true"_expect );
CHECK (format4Csv(bool(0)) == "false"_expect); CHECK (format4Csv(bool(0)) == "false"_expect);
CHECK (format4Csv("Starship-3") == "\"Starship-3\""_expect ); // 3rd test today ;-) CHECK (format4Csv("Starship-3") == "\"Starship-3\""_expect ); // 3rd test today ;-)

View file

@ -92,9 +92,9 @@ namespace test {
CHECK (a2.siz > 555); CHECK (a2.siz > 555);
// can use that memory without blowing up.... // can use that memory without blowing up....
auto doooh = new(a1.mem) f128{std::numeric_limits<f128>::max()}; auto doooh = new(a1.mem) lflo{std::numeric_limits<lflo>::max()};
*doooh /= 2; *doooh /= 2;
CHECK (2 == std::numeric_limits<f128>::max() / *doooh); CHECK (2 == std::numeric_limits<lflo>::max() / *doooh);
allo.deallocate (a1); allo.deallocate (a1);
allo.deallocate (a2); allo.deallocate (a2);