Parameters: solve mixed signed / unsigned computation
There are some corner cases where the C++ number promotion rules can hurt us badly. Devised a type selection logic to pick a suitable common numeric type explicitly, using `std::common_type<T1,T2>` in most cases, yet handling explicitly the case when the computation would wrap into unsigned; in such a mixed sign integral case, we either use int64_t (when its precision suffices), or long double, which can hold 64bit of mantissa without precision loss.
This commit is contained in:
parent
129eb0c1bd
commit
e3a8ce1b5e
4 changed files with 171 additions and 55 deletions
|
|
@ -207,6 +207,7 @@ namespace par {
|
||||||
return rawVal;
|
return rawVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Join and combine an additional feed value with an anchor value.
|
* Join and combine an additional feed value with an anchor value.
|
||||||
* @note actual joining operation is picked based on both scales and types involved.
|
* @note actual joining operation is picked based on both scales and types involved.
|
||||||
|
|
@ -218,6 +219,8 @@ namespace par {
|
||||||
Scale<VAL>::join (VAL const& value, SRC const& srcFeed, Scale<SRC> const& feedScale) const
|
Scale<VAL>::join (VAL const& value, SRC const& srcFeed, Scale<SRC> const& feedScale) const
|
||||||
{
|
{
|
||||||
VAL res{};
|
VAL res{};
|
||||||
|
using JoinT = NumberJoinType<VAL,SRC>;
|
||||||
|
|
||||||
if (NOM == metric)
|
if (NOM == metric)
|
||||||
UNIMPLEMENTED ("nominal and ordinal scales");
|
UNIMPLEMENTED ("nominal and ordinal scales");
|
||||||
if (LIN == metric)
|
if (LIN == metric)
|
||||||
|
|
@ -226,9 +229,9 @@ namespace par {
|
||||||
assignConverted (res, value * feedScale.template asFactor<VAL> (srcFeed));
|
assignConverted (res, value * feedScale.template asFactor<VAL> (srcFeed));
|
||||||
else
|
else
|
||||||
if (feedScale.isFactor())
|
if (feedScale.isFactor())
|
||||||
assignConverted (res, value * srcFeed);
|
assignConverted (res, JoinT(value) * JoinT(srcFeed));
|
||||||
else
|
else
|
||||||
assignConverted (res, value + srcFeed);
|
assignConverted (res, JoinT(value) + JoinT(srcFeed));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (this->isLogarithmic())
|
if (this->isLogarithmic())
|
||||||
|
|
@ -245,7 +248,8 @@ namespace par {
|
||||||
NOTREACHED ("Unexpected metric conversion case");
|
NOTREACHED ("Unexpected metric conversion case");
|
||||||
|
|
||||||
return conform (res);
|
return conform (res);
|
||||||
}
|
} // last step: re-establish target scale rules
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplified join() variant, assuming the feed is based on the same scale.
|
* Simplified join() variant, assuming the feed is based on the same scale.
|
||||||
|
|
@ -259,6 +263,9 @@ namespace par {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** transform a logarithmic value into an exponential factor */
|
/** transform a logarithmic value into an exponential factor */
|
||||||
template<typename VAL>
|
template<typename VAL>
|
||||||
template<typename TAR>
|
template<typename TAR>
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,11 @@ namespace par {
|
||||||
using std::signed_integral;
|
using std::signed_integral;
|
||||||
using std::floating_point;
|
using std::floating_point;
|
||||||
using std::numeric_limits;
|
using std::numeric_limits;
|
||||||
|
using std::common_type_t;
|
||||||
|
using std::is_signed_v;
|
||||||
|
using std::is_unsigned_v;
|
||||||
|
using std::is_integral_v;
|
||||||
|
using std::is_floating_point_v;
|
||||||
|
|
||||||
|
|
||||||
/* ===== type conversion implementation details ===== */
|
/* ===== type conversion implementation details ===== */
|
||||||
|
|
@ -154,9 +159,44 @@ _Pragma("GCC diagnostic pop")
|
||||||
* the best-precision floating point type to carry out
|
* the best-precision floating point type to carry out
|
||||||
* a numeric operation to combine two values
|
* a numeric operation to combine two values
|
||||||
*/
|
*/
|
||||||
template<number T, number U>
|
template<number V, number W>
|
||||||
using CommonComputeType = std::conditional_t<integral<T> and integral<U>, double
|
using CommonComputeType = std::conditional_t<integral<V> and integral<W>, double
|
||||||
, std::common_type_t<T, U>>;
|
, common_type_t<V, W>>;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
/** @internal decision logic for combining numeric parameters */
|
||||||
|
template<typename V, typename W>
|
||||||
|
auto
|
||||||
|
selectNumberJoinType()
|
||||||
|
{
|
||||||
|
if constexpr (is_floating_point_v<V> or is_floating_point_v<W>)
|
||||||
|
return std::type_identity<common_type_t<V,W>>{};
|
||||||
|
else
|
||||||
|
if constexpr (is_signed_v<V> == is_signed_v<W>)
|
||||||
|
return std::type_identity<common_type_t<V,W>>{};
|
||||||
|
else
|
||||||
|
{ // mixed signed/unsigned integral: need a type wide enough to accommodate.
|
||||||
|
using U = std::conditional_t<is_signed_v<V>, W,V>;
|
||||||
|
if constexpr (8 > sizeof(U))
|
||||||
|
return std::type_identity<int64_t>{};
|
||||||
|
else
|
||||||
|
return std::type_identity<f128>{};
|
||||||
|
// no standard integral type can hold uint64_t's full range signed.
|
||||||
|
// Expand to long double, which can hold 64bit without precision loss
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A common type to perform simple numeric operations safely.
|
||||||
|
* - when one of the type parameters is floating-point, computations switch over there
|
||||||
|
* - on integral types with same signedness, std::common_type handles a sane common ground
|
||||||
|
* - when mixed computations can be managed within signed 64bit, switch up to that
|
||||||
|
* - in the remaining problematic case(s), long double is used, as it can accommodate
|
||||||
|
* the full 64bit value range without loss on platforms relevant for Lumiera.
|
||||||
|
*/
|
||||||
|
template<typename A, typename B>
|
||||||
|
using NumberJoinType = typename decltype(selectNumberJoinType<A,B>())::type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,8 +177,12 @@ namespace test{
|
||||||
feedScale.metric = DEC; // in dB
|
feedScale.metric = DEC; // in dB
|
||||||
CHECK ( 7 == scale.join (4, int64_t(3), feedScale)); // 4 + 3dB ⟼ 4 * 1.995 ≡ 7.98 ⟼ truncated to 7
|
CHECK ( 7 == scale.join (4, int64_t(3), feedScale)); // 4 + 3dB ⟼ 4 * 1.995 ≡ 7.98 ⟼ truncated to 7
|
||||||
|
|
||||||
////////////////////////////OOO die folgende Konvertierung entgleist....
|
Scale<short> sscale;
|
||||||
SHOW_EXPR(short(-3) * uint64_t(2))
|
Scale<uint64_t> uscale = {.neutral = 1};
|
||||||
|
|
||||||
|
// Note: number promotion rules of C++ would backfire nastily here...
|
||||||
|
CHECK (short(-3) * uint64_t(2) > numeric_limits<int64_t>::max());
|
||||||
|
CHECK (short(-6) == sscale.join (-3, uint64_t(2), uscale));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85574,9 +85574,7 @@
|
||||||
<node CREATED="1789164561486" ID="ID_376197998" MODIFIED="1789164593909" TEXT="bedeutet: die darauf aufbauende Provision muß ggfs. einen double-Dispatch machen"/>
|
<node CREATED="1789164561486" ID="ID_376197998" MODIFIED="1789164593909" TEXT="bedeutet: die darauf aufbauende Provision muß ggfs. einen double-Dispatch machen"/>
|
||||||
<node CREATED="1789165221192" ID="ID_388299163" MODIFIED="1789687877259" TEXT="die Basis-Implementierung muß dann generisch sein und von Scale bereitgestellt werden">
|
<node CREATED="1789165221192" ID="ID_388299163" MODIFIED="1789687877259" TEXT="die Basis-Implementierung muß dann generisch sein und von Scale bereitgestellt werden">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
Zwar könnte man auch so argumentieren, daß zunächst der Quell-Feed so adaptiert werden sollte, daß der Basistyp gleich ist...
|
Zwar könnte man auch so argumentieren, daß zunächst der Quell-Feed so adaptiert werden sollte, daß der Basistyp gleich ist...
|
||||||
|
|
@ -85593,22 +85591,18 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1789165187065" ID="ID_1109273270" MODIFIED="1789165213989" TEXT="Konsequenz ⟹ die Scale muß hier zwei Typ-Parameter nehmen">
|
<node CREATED="1789165187065" ID="ID_1109273270" MODIFIED="1789165213989" TEXT="Konsequenz ⟹ die Scale muß hier zwei Typ-Parameter nehmen">
|
||||||
<node CREATED="1789679141799" ID="ID_907734481" MODIFIED="1789679174971" TEXT="die eigentliche Wert-Umwandlung ist hier vergleichsweise einfach">
|
<node CREATED="1789679141799" ID="ID_907734481" MODIFIED="1789679174971" TEXT="die eigentliche Wert-Umwandlung ist hier vergleichsweise einfach">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
...weil wir die Basis-Typen für Parameter entsprechend eingeschränkt haben
|
...weil wir die Basis-Typen für Parameter entsprechend eingeschränkt haben
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1789679178010" ID="ID_641923682" MODIFIED="1789679196411" TEXT="dazu genügt die preClamp-Funktion (generisch, mit Varianten)"/>
|
<node CREATED="1789679178010" ID="ID_641923682" MODIFIED="1789679196411" TEXT="dazu genügt die preClamp-Funktion (generisch, mit Varianten)"/>
|
||||||
<node CREATED="1789679234347" ID="ID_562560611" MODIFIED="1789679253968" TEXT="diese hängt aber (mit diversen weiteren Funktionen) in param-type.hpp"/>
|
<node CREATED="1789679234347" ID="ID_562560611" MODIFIED="1789679253968" TEXT="diese hängt aber (mit diversen weiteren Funktionen) in param-type.hpp"/>
|
||||||
|
|
@ -85660,29 +85654,23 @@
|
||||||
<icon BUILTIN="button_cancel"/>
|
<icon BUILTIN="button_cancel"/>
|
||||||
<node CREATED="1789864846110" ID="ID_1307210282" MODIFIED="1789865000390" TEXT="dieser Fall macht inhaltlich keinen Sinn">
|
<node CREATED="1789864846110" ID="ID_1307210282" MODIFIED="1789865000390" TEXT="dieser Fall macht inhaltlich keinen Sinn">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
man könnte hier zwar delogarithmieren / relogarithmieren, aber was ist z.B. bei negativem Ergebnis...? und, noch mehr: welchen Sinn hat es zu einem <i>multiplikativen Faktor</i> etwas hinzuzuaddieren (was aber nicht logarithmisch ist)
|
man könnte hier zwar delogarithmieren / relogarithmieren, aber was ist z.B. bei negativem Ergebnis...? und, noch mehr: welchen Sinn hat es zu einem <i>multiplikativen Faktor</i> etwas hinzuzuaddieren (was aber nicht logarithmisch ist)
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1789864856488" ID="ID_1180276604" MODIFIED="1789865677798" TEXT="diese Kombination kann eigentlich nur auf einen konzeptionellen Fehler hinweisen">
|
<node CREATED="1789864856488" ID="ID_1180276604" MODIFIED="1789865677798" TEXT="diese Kombination kann eigentlich nur auf einen konzeptionellen Fehler hinweisen">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
Logarithmische Metrik verwendet man nur, wenn auch die Größe, in ihrer Bedeutung für die Wahrnehmung, selber logarithmisch ist. Zwar könnte man sich rein-formal vorstellen, daß so ein Fall durchaus mal auftreten kann — aber dann wäre es besser, die Situation zu hinterfragen: fehlt da vielleicht die Markierung des Feed als <i>logarithmisch?</i>
|
Logarithmische Metrik verwendet man nur, wenn auch die Größe, in ihrer Bedeutung für die Wahrnehmung, selber logarithmisch ist. Zwar könnte man sich rein-formal vorstellen, daß so ein Fall durchaus mal auftreten kann — aber dann wäre es besser, die Situation zu hinterfragen: fehlt da vielleicht die Markierung des Feed als <i>logarithmisch?</i>
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
|
|
@ -85695,37 +85683,29 @@
|
||||||
<node CREATED="1789691697643" ID="ID_1724775924" MODIFIED="1789691708345" TEXT="von Integraltypen ⟹ stets double"/>
|
<node CREATED="1789691697643" ID="ID_1724775924" MODIFIED="1789691708345" TEXT="von Integraltypen ⟹ stets double"/>
|
||||||
<node CREATED="1789691709035" ID="ID_28970072" MODIFIED="1789691791715" TEXT="ansonsten maximalen floating-point-Typ">
|
<node CREATED="1789691709035" ID="ID_28970072" MODIFIED="1789691791715" TEXT="ansonsten maximalen floating-point-Typ">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
d.h. wenn beide Seiten float sind, dann ist das wohl auch so beabsichtigt, und wir bleiben in der float-Domäne. Ebenso wenn eine Seite long-double ist, dann alles dort. Sonst double verwenden
|
d.h. wenn beide Seiten float sind, dann ist das wohl auch so beabsichtigt, und wir bleiben in der float-Domäne. Ebenso wenn eine Seite long-double ist, dann alles dort. Sonst double verwenden
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
</node>
|
</node>
|
||||||
<node COLOR="#435e98" CREATED="1789869944433" ID="ID_1523483246" MODIFIED="1789877469677" TEXT="sollte das als Typedef ausdrücken: CommonComputeType<T,U>">
|
<node COLOR="#435e98" CREATED="1789869944433" ID="ID_1523483246" MODIFIED="1789877469677" TEXT="sollte das als Typedef ausdrücken: CommonComputeType<T,U>">
|
||||||
<icon BUILTIN="yes"/>
|
<icon BUILTIN="yes"/>
|
||||||
<node CREATED="1789869964502" ID="ID_1289831616" MODIFIED="1789869996988" TEXT="geht nicht als Serie von constrained templates">
|
<node CREATED="1789869964502" ID="ID_1289831616" MODIFIED="1789869996988" TEXT="geht nicht als Serie von constrained templates">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
...weil sich die Constraints typischerweise überlappen
|
...weil sich die Constraints typischerweise überlappen
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1789869998707" ID="ID_221126714" MODIFIED="1789870032835" TEXT="dann doch die Bedingung als std::contditional_t ausformulieren">
|
<node CREATED="1789869998707" ID="ID_221126714" MODIFIED="1789870032835" TEXT="dann doch die Bedingung als std::contditional_t ausformulieren">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<div style="background-color: #eee0b5; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 2px">
|
<div style="background-color: #eee0b5; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 2px">
|
||||||
<div style="color: #202020; background-color: #eee0b5; font-family: DejaVu Sans Mono; font-size: 9pt; white-space: pre">
|
<div style="color: #202020; background-color: #eee0b5; font-family: DejaVu Sans Mono; font-size: 9pt; white-space: pre">
|
||||||
|
|
@ -85766,22 +85746,79 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
<icon BUILTIN="idea"/>
|
<icon BUILTIN="idea"/>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1789876376322" ID="ID_1223578931" MODIFIED="1789876404350" TEXT="eigentliche Join-Operation in auf passendem Zwischentyp ausführen">
|
<node COLOR="#338800" CREATED="1789876376322" ID="ID_1223578931" MODIFIED="1789949324151" TEXT="eigentliche Join-Operation in auf passendem Zwischentyp ausführen">
|
||||||
<icon BUILTIN="pencil"/>
|
<linktarget COLOR="#28b55c" DESTINATION="ID_1223578931" ENDARROW="Default" ENDINCLINATION="-139;1297;" ID="Arrow_ID_225645373" SOURCE="ID_1294384495" STARTARROW="None" STARTINCLINATION="111;6;"/>
|
||||||
<node CREATED="1789876405765" ID="ID_1109556835" MODIFIED="1789876417629" TEXT="CommonComputeType verwenden"/>
|
<icon BUILTIN="button_ok"/>
|
||||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1789876423793" ID="ID_603151342" MODIFIED="1789877266018" TEXT="Vorsicht Falle: Kombination von signed/unsigned">
|
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1789876423793" ID="ID_603151342" MODIFIED="1789877266018" TEXT="Vorsicht Falle: Kombination von signed/unsigned">
|
||||||
<icon BUILTIN="broken-line"/>
|
<icon BUILTIN="broken-line"/>
|
||||||
<node CREATED="1789877276449" ID="ID_1205492042" MODIFIED="1789877286892" TEXT="kann mich nicht allein auf die number-promotion verlassen"/>
|
<node CREATED="1789877276449" ID="ID_1205492042" MODIFIED="1789877286892" TEXT="kann mich nicht allein auf die number-promotion verlassen"/>
|
||||||
<node CREATED="1789877306308" ID="ID_1833375564" MODIFIED="1789877330237" TEXT="Gegenbeispiel: short(-3) * uint64_t(2)"/>
|
<node CREATED="1789877306308" ID="ID_1833375564" MODIFIED="1789877330237" TEXT="Gegenbeispiel: short(-3) * uint64_t(2)"/>
|
||||||
</node>
|
</node>
|
||||||
|
<node CREATED="1789876405765" ID="ID_1109556835" MODIFIED="1789877918151" TEXT="CommonComputeType verwenden">
|
||||||
|
<icon BUILTIN="idea"/>
|
||||||
|
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1789877920344" ID="ID_640203687" MODIFIED="1789877965236" STYLE="fork" TEXT="damit gehen aber nun auch einfache Additionen über floating-point — wollen wir das?">
|
||||||
|
<icon BUILTIN="messagebox_warning"/>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1789691232896" ID="ID_575039816" MODIFIED="1789691803456" TEXT="Konvertierung in den Ziel-Typ stets zuletzt (vor Conform)"/>
|
<node CREATED="1789878009733" ID="ID_1316581925" MODIFIED="1789878034175" TEXT="könnte in dem Fall eine Verfeinerung machen">
|
||||||
|
<node CREATED="1789878125407" ID="ID_1221061821" MODIFIED="1789878140752" TEXT="das sollte nur in dem problematischen Fall greifen"/>
|
||||||
|
<node CREATED="1789878141565" ID="ID_1028048071" MODIFIED="1789878149899" TEXT="also promotion to larger unsigned"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1789944510715" ID="ID_746993319" MODIFIED="1789944521564" TEXT="Claude beauftragt">
|
||||||
|
<icon BUILTIN="wizard"/>
|
||||||
|
<node CREATED="1789944530056" ID="ID_1759698759" MODIFIED="1789949125520" TEXT="schlägt eine Logik-Kaskade in Metaprogramming vor">
|
||||||
|
<icon BUILTIN="info"/>
|
||||||
|
<node CREATED="1789944639760" ID="ID_1968290680" MODIFIED="1789944654204" TEXT="floating-point ⟹ common_type macht die Arbeit"/>
|
||||||
|
<node CREATED="1789944655000" ID="ID_1256360330" MODIFIED="1789944661011" TEXT="gleiche signedness ⟹ dto"/>
|
||||||
|
<node CREATED="1789944662174" ID="ID_555669740" MODIFIED="1789944682944" TEXT="Bitlänge prüfen ⟹ wenn ausreichend, int64_t"/>
|
||||||
|
<node CREATED="1789944684283" ID="ID_257781335" MODIFIED="1789945256482">
|
||||||
|
<richcontent TYPE="NODE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
sonst: Promotion in <b>long double</b>
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
bei letzterem hab ich nachgehakt, Claude hat zunächst double vorgeschlagen.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Einsichten:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
double kann keinen uint64_t exakt halten (das wußte ich)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
long double ist auf x64 entweder 80bit oder 128 bit, also ausreichend
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1789944547766" ID="ID_1252274825" MODIFIED="1789945715864" TEXT="verwendet std::type_identity<T> um den Ergebnistyp aus einer Funktion zu liefern">
|
||||||
|
<arrowlink COLOR="#8794ab" DESTINATION="ID_921530714" ENDARROW="Default" ENDINCLINATION="-2571;328;" ID="Arrow_ID_1292265667" STARTARROW="None" STARTINCLINATION="-3659;127;"/>
|
||||||
|
<icon BUILTIN="idea"/>
|
||||||
|
<node CREATED="1789944580961" ID="ID_354835013" MODIFIED="1789944589683" TEXT="Ha! den Trick kannte ich noch nicht">
|
||||||
|
<icon BUILTIN="ksmiletris"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node COLOR="#338800" CREATED="1789944608086" ID="ID_688346228" MODIFIED="1789949122394" TEXT="gefält mir gut: der einzige problematische Fall steht als eigener Zweig">
|
||||||
|
<icon BUILTIN="ksmiletris"/>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
</node>
|
||||||
|
<node CREATED="1789691232896" ID="ID_575039816" MODIFIED="1789945553816" TEXT="Konvertierung in den Ziel-Typ stets zuletzt (vor Conform)"/>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1789691159130" ID="ID_1328281700" MODIFIED="1789691168924" TEXT="zuletzt Conform() anwenden"/>
|
<node CREATED="1789691159130" ID="ID_1328281700" MODIFIED="1789691168924" TEXT="zuletzt Conform() anwenden"/>
|
||||||
<node CREATED="1789691889609" ID="ID_569629897" MODIFIED="1789691899860" TEXT="Formulierung: muß Funktions-Kette bilden"/>
|
<node CREATED="1789691889609" ID="ID_569629897" MODIFIED="1789691899860" TEXT="Formulierung: muß Funktions-Kette bilden"/>
|
||||||
|
|
@ -87214,8 +87251,18 @@ Prop.1: dist%3 1 2 0 1 2 0
|
||||||
<icon BUILTIN="button_ok"/>
|
<icon BUILTIN="button_ok"/>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1789172002831" ID="ID_939833813" MODIFIED="1789172009585" TEXT="gemische Scales handhaben">
|
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1789172002831" ID="ID_939833813" MODIFIED="1789949264299" TEXT="gemische Scales handhaben">
|
||||||
<icon BUILTIN="flag-yellow"/>
|
<icon BUILTIN="pencil"/>
|
||||||
|
<node COLOR="#338800" CREATED="1789949153983" ID="ID_781783423" MODIFIED="1789949195612" TEXT="ushort-Scale mit Limits ⟵ kombiniert mit int64_t">
|
||||||
|
<icon BUILTIN="button_ok"/>
|
||||||
|
</node>
|
||||||
|
<node COLOR="#338800" CREATED="1789949198651" ID="ID_294918713" MODIFIED="1789949239261" TEXT="Varianten mit »multiplicative« und deciBel">
|
||||||
|
<icon BUILTIN="button_ok"/>
|
||||||
|
</node>
|
||||||
|
<node COLOR="#338800" CREATED="1789949240757" ID="ID_1294384495" MODIFIED="1789949324151" TEXT="sicheres Umgehen der unsigned/signed-Problematik">
|
||||||
|
<arrowlink COLOR="#28b55c" DESTINATION="ID_1223578931" ENDARROW="Default" ENDINCLINATION="-139;1297;" ID="Arrow_ID_225645373" STARTARROW="None" STARTINCLINATION="111;6;"/>
|
||||||
|
<icon BUILTIN="button_ok"/>
|
||||||
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
|
|
@ -87455,9 +87502,7 @@ Prop.1: dist%3 1 2 0 1 2 0
|
||||||
<icon BUILTIN="button_ok"/>
|
<icon BUILTIN="button_ok"/>
|
||||||
<node CREATED="1789607298013" ID="ID_452068382" MODIFIED="1789607555871" TEXT="im Grunde offensichtlich und redundant">
|
<node CREATED="1789607298013" ID="ID_452068382" MODIFIED="1789607555871" TEXT="im Grunde offensichtlich und redundant">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
...da ein Test eigentlich mehr machen sollte, als nur nochmal den Code zu wiederholen; und hier passiert nicht mehr, als ein cap an der boundrary, auf einem komplett offensichtlichen und einfachen Code-Pfad
|
...da ein Test eigentlich mehr machen sollte, als nur nochmal den Code zu wiederholen; und hier passiert nicht mehr, als ein cap an der boundrary, auf einem komplett offensichtlichen und einfachen Code-Pfad
|
||||||
|
|
@ -87472,9 +87517,7 @@ Prop.1: dist%3 1 2 0 1 2 0
|
||||||
<icon BUILTIN="button_ok"/>
|
<icon BUILTIN="button_ok"/>
|
||||||
<node CREATED="1789607356261" ID="ID_1762601340" MODIFIED="1789607743052" TEXT="auch hier nur bedingt sinnvoll testbar">
|
<node CREATED="1789607356261" ID="ID_1762601340" MODIFIED="1789607743052" TEXT="auch hier nur bedingt sinnvoll testbar">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head/>
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
<body>
|
||||||
<p>
|
<p>
|
||||||
...denn die eigentlich trickreiche Funktionalität steckt in der Library-Funktion und ist dort schon per Unit-Test abgedeckt, und das korrekte Setup wird innerhalb des Scale-Descriptors gar nicht geprüft (weil diese Prüfung in den umschließenden Kontext gehört, wo die Scale in einen Parameter-Typ eingebunden wird)
|
...denn die eigentlich trickreiche Funktionalität steckt in der Library-Funktion und ist dort schon per Unit-Test abgedeckt, und das korrekte Setup wird innerhalb des Scale-Descriptors gar nicht geprüft (weil diese Prüfung in den umschließenden Kontext gehört, wo die Scale in einen Parameter-Typ eingebunden wird)
|
||||||
|
|
@ -188878,6 +188921,28 @@ std::cout << tmpl.render({"what", "World"}) << s
|
||||||
</body>
|
</body>
|
||||||
</html></richcontent>
|
</html></richcontent>
|
||||||
</node>
|
</node>
|
||||||
|
<node CREATED="1789945524270" ID="ID_921530714" MODIFIED="1789945715864" TEXT="std::type_identity<T>">
|
||||||
|
<richcontent TYPE="NOTE"><html>
|
||||||
|
<head/>
|
||||||
|
<body>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Ist nur eine ansonsten leere Struct mit einer typedef "type = T"
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
also die »Identity«-Metafunktion
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
nützlich um eine Typ-Entscheidungslogik in einer Funktion per constexpr-if zu formulieren
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
und natürlich allgemein, um Typen als first-class-citizens weiterzugeben
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html></richcontent>
|
||||||
|
<linktarget COLOR="#8794ab" DESTINATION="ID_921530714" ENDARROW="Default" ENDINCLINATION="-2571;328;" ID="Arrow_ID_1292265667" SOURCE="ID_1252274825" STARTARROW="None" STARTINCLINATION="-3659;127;"/>
|
||||||
|
</node>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1617648907316" FOLDED="true" ID="ID_899199723" MODIFIED="1617650703506" TEXT="Coroutine">
|
<node CREATED="1617648907316" FOLDED="true" ID="ID_899199723" MODIFIED="1617650703506" TEXT="Coroutine">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue