Compare commits

...

3 commits

Author SHA1 Message Date
620ca918c3 Library: verification for all floating-point types
finally I was able to come up with a rather concise test
that works with float, double and long double; especially
the aliasing due to rounding could be demonstrated, and
the precision limit is made plausible.

Interestingly, `std::fabs()` really works precise enough
so that a very large positive domain can be implemented
and tested with exact match
2026-09-16 04:23:55 +02:00
0c69db19d7 Library: investigate what could be tested with floating-point
The floating-point variant turns out to be difficult to test,
since it is never ''actually exact'' -- due to the nature of floating-points.

We can not expect reasonable behaviour at the domain boundaries,
even while in some cases the computation works (and in others it
goes infinite and is sanitised to `minVal`).

The limit for rejection is itself rather a heuristic;
thus it is difficult to show "wrong" behaviour beyond the limit,
while the limit itself is typically already so large that it is
hard to handle in test code -- at least when expecting visible results.
2026-09-15 21:53:56 +02:00
078aa48879 Library: verify the new cyclicWrap library function
The implementation should cover all integral data types,
both signed and signed, over the entire value domain.

Verify that by testing the bounds and the complex computation path
2026-09-15 01:37:38 +02:00
4 changed files with 392 additions and 12 deletions

View file

@ -216,7 +216,7 @@ namespace util {
offset += PERIOD;
if (not (offset < PERIOD)) // can happen due to ε or non-finite values
offset = 0;
F res = minVal + offset; // could be rounded to maxVal
F res = minVal + offset; // could be rounded to maxVal (or become infinite)
return res < maxVal? res : minVal;
}
@ -245,6 +245,7 @@ namespace util {
limit_cyclicWrap (F period)
{
REQUIRE (std::isfinite (period));
REQUIRE (F(0) < period);
F limit = period / std::numeric_limits<F>::epsilon();
if (not std::isfinite (limit))
limit = std::numeric_limits<F>::max();

View file

@ -53,6 +53,11 @@ return: 0
END
TEST "Cyclic wrapping number domain" CyclicWrap_test <<END
return: 0
END
TEST "Deleter function collection" DelStash_test <<END
return: 0
END

View file

@ -0,0 +1,197 @@
/*
CyclicWrap(Test) - verify cyclically wrapping number domain
Copyright (C)
2026, Hermann Vosseler <Ichthyostega@web.de>
  **Lumiera** is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2 of the License, or (at your
  option) any later version. See the file COPYING for further details.
* *****************************************************************/
/** @file util-floordiv-test.cpp
** unit test \ref CyclicWrap_test
*/
#include "test/run.hpp"
#include "lib/util-quant.hpp"
#include "lib/util.hpp"
using ::Test;
using util::isLimited;
using std::floating_point;
namespace util {
namespace test {
namespace{ // Test helpers...
template<typename NUM>
constexpr NUM _MAX = std::numeric_limits<NUM>::max();
template<typename NUM>
constexpr NUM _MIN = std::numeric_limits<NUM>::lowest();
template<floating_point FLO>
constexpr FLO _EPS = std::numeric_limits<FLO>::epsilon();
} // (End) Test helpers
/******************************************************************//**
* @test Demonstrate and verify a cyclic wrapping numeric domain.
* - show the wrapping behaviour with simple numbers
* - verify the behaviour pattern for all integer types (signed / unsigned)
* - verify the computation works at the very bounds of the domain
* - verify the most difficult path with a negative minVal,
* and the smallest number in the domain
* - show a similar simple wrapping behaviour with all float types
* - demonstrate the meaning of the precision limit
* - demonstrate aliasing and sanitised rounding errors
* @see util::cyclicWrap
* @see parameter-scale-test.cpp
*/
class CyclicWrap_test : public Test
{
virtual void
run (Arg)
{
simpleDemonstration();
verifyIntegerTypes<int>();
verifyIntegerTypes<uint>();
verifyIntegerTypes<int8_t>();
verifyIntegerTypes<uint8_t>();
verifyIntegerTypes<int16_t> ();
verifyIntegerTypes<uint16_t>();
verifyIntegerTypes<int32_t> ();
verifyIntegerTypes<uint32_t>();
verifyIntegerTypes<int64_t> ();
verifyIntegerTypes<uint64_t>();
verifyFloatTypes<float>();
verifyFloatTypes<double>();
verifyFloatTypes<f128>();
}
void
simpleDemonstration ()
{
CHECK (10 == cyclicWrap (10,10,15));
CHECK (11 == cyclicWrap (11,10,15));
CHECK (12 == cyclicWrap (12,10,15));
CHECK (13 == cyclicWrap (13,10,15));
CHECK (14 == cyclicWrap (14,10,15));
CHECK (10 == cyclicWrap (15,10,15));
CHECK (11 == cyclicWrap (16,10,15));
CHECK (12 == cyclicWrap (17,10,15));
CHECK (13 == cyclicWrap (18,10,15));
CHECK (14 == cyclicWrap (19,10,15));
CHECK (10 == cyclicWrap (20,10,15));
CHECK (10 == cyclicWrap ( 0,10,15));
CHECK (14 == cyclicWrap (-1,10,15));
}
template<typename I>
void
verifyIntegerTypes ()
{
const I LOWER(-100); // note: expected to wrap for unsigned types
const I UPPER(LOWER+5);
auto cyc = [&](I val){ return cyclicWrap (val, LOWER,UPPER); };
CHECK (LOWER == cyc(LOWER+0) );
CHECK (LOWER+1 == cyc(LOWER+1) );
CHECK (LOWER+2 == cyc(LOWER+2) );
CHECK (LOWER+3 == cyc(LOWER+3) );
CHECK (LOWER+4 == cyc(LOWER+4) );
CHECK (LOWER == cyc(LOWER+5) );
CHECK (LOWER == cyc(LOWER-5) );
CHECK (LOWER+1 == cyc(LOWER-4) );
CHECK (LOWER+2 == cyc(LOWER-3) );
CHECK (LOWER+3 == cyc(LOWER-2) );
CHECK (LOWER+4 == cyc(LOWER-1) );
CHECK (isLimited (LOWER, cyc(_MAX<I>), UPPER));
CHECK (isLimited (LOWER, cyc(_MIN<I>), UPPER));
CHECK (isLimited (LOWER, cyc(_MAX<I>-1), UPPER));
CHECK (isLimited (LOWER, cyc(_MIN<I>+1), UPPER));
//------ Demonstrate behaviour at lower domain bound
//
I dist = LOWER - _MIN<I>; // guaranteed to be positive and representable in-domain
I step = (dist / 5) * 5; // the next applicable grid point
I excess = dist - step;
I offset = 5 - excess; // flip orientation (since the input val lies below LOWER)
CHECK (LOWER + offset == cyc(_MIN<I>) );
}
template<typename F>
void
verifyFloatTypes()
{
auto cyc = [&](F val){ return cyclicWrap (val, F(-10),F(-5)); };
CHECK (almostEqual (F(-10), cyc(0)) );
CHECK (almostEqual (F( -9), cyc(1)) );
CHECK (almostEqual (F( -8), cyc(2)) );
CHECK (almostEqual (F( -7), cyc(3)) );
CHECK (almostEqual (F( -6), cyc(4)) );
CHECK (almostEqual (F(-10), cyc(5)) );
CHECK (almostEqual (F( -9), cyc(6)) );
CHECK (almostEqual (F( -8), cyc(7)) );
CHECK (almostEqual (F( -7), cyc(8)) );
CHECK (almostEqual (F( -6), cyc(9)) );
CHECK (almostEqual (F(-10), cyc(105)));
// For each period-length, a precision limit can be computed;
// whenever bounds or inputs approach that limit, the rounding errors
// approach the order of magnitude of the period-length, and thus
// computing of wrapped values becomes pointless...
F period5 = F(5);
F limit5 = limit_cyclicWrap<F> (period5);
// one ULP-Step at the limit equals already half the period-length:
CHECK (almostEqual (period5/2, limit5 * _EPS<F>));
// so small steps will alias...
CHECK (limit5 + 1 == limit5);
// HOWEWER, very large periods can be handled (within numeric precision)
CHECK (1 == cyclicWrap<F>( 1, 1,_MAX<F>) );
CHECK (2 == cyclicWrap<F>( 2, 1,_MAX<F>) ); // note: these values are *exact* -- due to std::fmod()
CHECK (3 == cyclicWrap<F>( 3, 1,_MAX<F>) );
CHECK (4 == cyclicWrap<F>( 4, 1,_MAX<F>) );
CHECK (5 == cyclicWrap<F>( 5, 1,_MAX<F>) );
CHECK (1 == cyclicWrap<F>(-1, 1,_MAX<F>) ); // yet this one gets aliased with the minVal
F epsStep = _MAX<F>*_EPS<F>;
// yet the following input is clearly below minVal and will wrap upwards...
F wrapped = cyclicWrap (-epsStep, F(1),_MAX<F>);
CHECK ( 1 < wrapped);
CHECK (wrapped < _MAX<F>);
}
};
LAUNCHER (CyclicWrap_test, "unit common");
}} // namespace util::test

View file

@ -86141,7 +86141,7 @@ class ScaleRegistry
</body>
</html></richcontent>
</node>
<node CREATED="1789313909221" ID="ID_636669321" MODIFIED="1789314360236">
<node CREATED="1789313909221" ID="ID_636669321" MODIFIED="1789423588613">
<richcontent TYPE="NODE"><html>
<head/>
<body>
@ -86158,7 +86158,8 @@ class ScaleRegistry
</p>
</body>
</html></richcontent>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1789314198004" ID="ID_1198665569" MODIFIED="1789314547810" TEXT="Integral: Abdeckung der gesamten Dom&#xe4;ne per Unsigned...">
<linktarget COLOR="#49a8d6" DESTINATION="ID_636669321" ENDARROW="Default" ENDINCLINATION="87;46;" ID="Arrow_ID_1613615444" SOURCE="ID_945572666" STARTARROW="None" STARTINCLINATION="260;14;"/>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1789314198004" FOLDED="true" ID="ID_1198665569" MODIFIED="1789423416268" TEXT="Integral: Abdeckung der gesamten Dom&#xe4;ne per Unsigned...">
<icon BUILTIN="wizard"/>
<node CREATED="1789314266561" ID="ID_662274868" MODIFIED="1789342378691" STYLE="bubble">
<richcontent TYPE="NODE"><html>
@ -86257,7 +86258,7 @@ class ScaleRegistry
<icon BUILTIN="wizard"/>
</node>
</node>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1789314221349" ID="ID_63841523" MODIFIED="1789314713492" TEXT="Floatingpoint: Nicht-handhabbare Bereiche beachten...">
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1789314221349" FOLDED="true" ID="ID_63841523" MODIFIED="1789423414551" TEXT="Floatingpoint: Nicht-handhabbare Bereiche beachten...">
<icon BUILTIN="wizard"/>
<node CREATED="1789314574790" HGAP="49" ID="ID_1659421158" MODIFIED="1789341131113" STYLE="bubble" VSHIFT="1">
<richcontent TYPE="NODE"><html>
@ -86337,7 +86338,7 @@ class ScaleRegistry
</node>
</node>
</node>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1789314739520" ID="ID_900911623" MODIFIED="1789314802300" TEXT="Erl&#xe4;uterung der L&#xf6;ungsstrategie">
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1789314739520" FOLDED="true" ID="ID_900911623" MODIFIED="1789423604616" TEXT="Erl&#xe4;uterung der L&#xf6;ungsstrategie">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -86527,7 +86528,7 @@ class ScaleRegistry
</p>
</body>
</html></richcontent>
<node BACKGROUND_COLOR="#f8ecbf" CREATED="1789340923095" HGAP="104" ID="ID_921584380" MODIFIED="1789347764151" VSHIFT="56">
<node BACKGROUND_COLOR="#f8ecbf" CREATED="1789340923095" HGAP="104" ID="ID_921584380" MODIFIED="1789423600852" VSHIFT="56">
<richcontent TYPE="NODE"><html>
<head/>
<body>
@ -86769,13 +86770,14 @@ Prop.1: dist%3 1 2 0 1 2 0
</p>
</body>
</html></richcontent>
<linktarget COLOR="#f8263e" DESTINATION="ID_921584380" ENDARROW="Default" ENDINCLINATION="-16;141;" ID="Arrow_ID_244758209" SOURCE="ID_380512260" STARTARROW="None" STARTINCLINATION="195;11;"/>
<linktarget COLOR="#ff0808" DESTINATION="ID_921584380" ENDARROW="Default" ENDINCLINATION="305;-925;" ID="Arrow_ID_153243460" SOURCE="ID_662274868" STARTARROW="None" STARTINCLINATION="141;26;"/>
<linktarget COLOR="#f8263e" DESTINATION="ID_921584380" ENDARROW="Default" ENDINCLINATION="-16;141;" ID="Arrow_ID_244758209" SOURCE="ID_380512260" STARTARROW="None" STARTINCLINATION="198;10;"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#aff8e9" COLOR="#338800" CREATED="1789340798664" HGAP="15" ID="ID_1175604381" MODIFIED="1789340850559" TEXT="damit k&#xf6;nnte ich implementieren..." VSHIFT="18">
<icon BUILTIN="idea"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1789340871908" ID="ID_380512260" MODIFIED="1789342452121" STYLE="fork" TEXT="die Erl&#xe4;uterung f&#xfc;r den Unsigned-Fall ist zu knapp">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1789340871908" ID="ID_380512260" MODIFIED="1789423600852" STYLE="fork" TEXT="die Erl&#xe4;uterung f&#xfc;r den Unsigned-Fall ist zu knapp">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -86784,7 +86786,7 @@ Prop.1: dist%3 1 2 0 1 2 0
</p>
</body>
</html></richcontent>
<arrowlink COLOR="#f8263e" DESTINATION="ID_921584380" ENDARROW="Default" ENDINCLINATION="-16;141;" ID="Arrow_ID_244758209" STARTARROW="None" STARTINCLINATION="195;11;"/>
<arrowlink COLOR="#f8263e" DESTINATION="ID_921584380" ENDARROW="Default" ENDINCLINATION="-16;141;" ID="Arrow_ID_244758209" STARTARROW="None" STARTINCLINATION="198;10;"/>
<font NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="broken-line"/>
</node>
@ -86806,13 +86808,14 @@ Prop.1: dist%3 1 2 0 1 2 0
</node>
<node CREATED="1789356710360" ID="ID_521207014" MODIFIED="1789356723054" TEXT="der -1-Verschiebe-Trick nutzt Modulus-Arithmetik"/>
</node>
<node CREATED="1789360000999" ID="ID_879348844" MODIFIED="1789360029799" TEXT="die Limit-Definition sollte direkt bei der cyclicWrap-Funktion selber definiert sein"/>
<node COLOR="#435e98" CREATED="1789360000999" ID="ID_879348844" MODIFIED="1789423630533" TEXT="die Limit-Definition sollte direkt bei der cyclicWrap-Funktion selber definiert sein">
<icon BUILTIN="yes"/>
</node>
</node>
</node>
</node>
<node CREATED="1789258808256" ID="ID_1240046297" MODIFIED="1789258815646" TEXT="Einf&#xfc;hren der Fallunterscheidung">
<node CREATED="1789258816860" ID="ID_1706182584" MODIFIED="1789258941151" TEXT="Policy-based Design erscheint die sauberste L&#xf6;sung">
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1789258816860" ID="ID_1706182584" MODIFIED="1789423431524" TEXT="Policy-based Design erscheint die sauberste L&#xf6;sung">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
@ -86822,8 +86825,182 @@ Prop.1: dist%3 1 2 0 1 2 0
</body>
</html></richcontent>
<icon BUILTIN="yes"/>
<icon BUILTIN="hourglass"/>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1789313641938" ID="ID_1271083241" MODIFIED="1789423457169" TEXT="zun&#xe4;chst gen&#xfc;gt eine generische Library-funktion als Delegate">
<icon BUILTIN="forward"/>
</node>
</node>
<node COLOR="#338800" CREATED="1789423486714" ID="ID_253445206" MODIFIED="1789438207120" TEXT="neue Implementierung">
<icon BUILTIN="button_ok"/>
<node CREATED="1789423493685" ID="ID_1410459624" MODIFIED="1789423506223" TEXT="entwickelt ausgehend von der naiven &#xbb;modulus&#xab;-L&#xf6;sung"/>
<node BACKGROUND_COLOR="#accdc3" COLOR="#3f4015" CREATED="1789423507714" ID="ID_945572666" MODIFIED="1789423613866" TEXT="zu einer generischen L&#xf6;sung ausgebaut &#x27f5; Claude">
<arrowlink COLOR="#49a8d6" DESTINATION="ID_636669321" ENDARROW="Default" ENDINCLINATION="87;46;" ID="Arrow_ID_1613615444" STARTARROW="None" STARTINCLINATION="260;14;"/>
<icon BUILTIN="wizard"/>
</node>
<node COLOR="#338800" CREATED="1789423635808" ID="ID_840921741" MODIFIED="1789525417179" TEXT="Testabdeckung &#x2014; Grenzf&#xe4;lle">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1789428970477" FOLDED="true" ID="ID_1439061940" MODIFIED="1789525368840" TEXT="habe gestern schon gesehen: f&#xfc;r sich sind util::flordiv | wrap wohl &#x201e;wasserdicht&#x201c;">
<icon BUILTIN="idea"/>
<node CREATED="1789429005712" ID="ID_1890368766" MODIFIED="1789429031093" TEXT="die Division liefert stets einen kleineren Quotient als der Dividend"/>
<node CREATED="1789429032161" ID="ID_1469836197" MODIFIED="1789429058156" TEXT="die Korrektur-Logik arbeitet &#xbb;gl&#xfc;cklicherweise&#xab; stets zur Dom&#xe4;ne nach innen"/>
<node COLOR="#338800" CREATED="1789433766523" ID="ID_167005830" MODIFIED="1789433779815" TEXT="dies in UtilFloordiv_test dokumentieren">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1789433789808" ID="ID_538605241" MODIFIED="1789433827387" TEXT="jeweils an die Domain-Ober/Untergrenze gehen"/>
<node COLOR="#435e98" CREATED="1789433801119" ID="ID_1533251912" MODIFIED="1789433827418" TEXT="durch 1, 2 und 5 teilen"/>
<node COLOR="#435e98" CREATED="1789433808102" ID="ID_1210053047" MODIFIED="1789433827419" TEXT="Vorzeichen wechseln"/>
<node COLOR="#435e98" CREATED="1789433812805" ID="ID_1425318347" MODIFIED="1789433827421" TEXT="auch f&#xfc;r uint, int64_t, int8_t"/>
</node>
</node>
<node COLOR="#338800" CREATED="1789437807095" ID="ID_932126209" MODIFIED="1789437907066" TEXT="zun&#xe4;chst eine einfache Demonstration (als Dokumentation)">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
.... ich k&#246;nnte mir denken, da&#223; mancher Leser das Konzept nicht gleich versteht, deshalb ist ein solches einfaches Beispiel nie verkehrt
</p>
</body>
</html></richcontent>
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1789437908944" FOLDED="true" ID="ID_880098415" MODIFIED="1789525347778" TEXT="systematisch alle real-existierenden Integral-Typen abdecken">
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1789437929974" ID="ID_532498668" MODIFIED="1789438198770" TEXT="die eigentliche Test-Funktion als Template">
<icon BUILTIN="idea"/>
</node>
<node COLOR="#338800" CREATED="1789437943780" ID="ID_1291965296" MODIFIED="1789438178462" TEXT="konstruiere das Test-Beispiel &#xbb;trickreich&#xab;">
<icon BUILTIN="button_ok"/>
<node CREATED="1789437965201" ID="ID_1576393662" MODIFIED="1789437977028" TEXT="so da&#xdf; es sich f&#xfc;r Signed und Unsigned gut testen l&#xe4;&#xdf;t"/>
<node CREATED="1789437977859" ID="ID_1376129649" MODIFIED="1789438001984" TEXT="soll aber auch den komplexeren Pfad ausleuchten"/>
<node CREATED="1789438002860" ID="ID_1338563274" MODIFIED="1789438069296" TEXT="&#x27f9; sollte die zyklische Dom&#xe4;ne in den negativen Bereich legen">
<node CREATED="1789438070916" ID="ID_379253711" MODIFIED="1789438081989" TEXT="f&#xfc;r Unsigned sollte das wrappen"/>
<node CREATED="1789438082993" ID="ID_1576673426" MODIFIED="1789438091635" TEXT="aber trotzdem noch sicher in die Dom&#xe4;ne passen"/>
<node CREATED="1789438092936" ID="ID_1900067766" MODIFIED="1789438108922" TEXT="und f&#xfc;r Signed ist dann der Offset garantiert repr&#xe4;sentierbar"/>
<node CREATED="1789438111305" ID="ID_1260779668" MODIFIED="1789438125620" TEXT="und zwar grade f&#xfc;r den problematischen Fall unter der Untergrenze"/>
</node>
</node>
<node COLOR="#338800" CREATED="1789438130012" ID="ID_1945361876" MODIFIED="1789438175874" TEXT="teste die Dom&#xe4;nen-Grenzen auf valides Ergebnis (in der zyklischen Domain)">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1789438158204" ID="ID_527867911" MODIFIED="1789438175875" TEXT="rechne explizit den Wert f&#xfc;r die Domain-Untergrenze nach">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1789485850174" FOLDED="true" ID="ID_1074654514" MODIFIED="1789525408140" TEXT="systematische Testabdeckung f&#xfc;r Floatingpoint-Typen entwickeln">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1789485871331" ID="ID_552981037" MODIFIED="1789525115154" TEXT="mu&#xdf; zun&#xe4;chst einmal herausfinden was man &#xfc;berhaupt testen k&#xf6;nnte">
<icon BUILTIN="yes"/>
<node CREATED="1789485882603" ID="ID_1932453860" MODIFIED="1789485901968" TEXT="geschenkt: einen einfachen cyclicWrap">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
ganz analog zum Integral-Fall
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1789485908054" ID="ID_1390215073" MODIFIED="1789485917984" TEXT="mit dem Verhalten am Limit experimentieren"/>
<node CREATED="1789485919101" ID="ID_126516087" MODIFIED="1789485942979" TEXT="Limit-Werte anschauen &#x27f9; sie wachsen mit der Periodenl&#xe4;nge"/>
<node CREATED="1789485944250" ID="ID_758296300" MODIFIED="1789485958924" TEXT="man k&#xf6;nnte also mit Input knapp unter dem Limit testen"/>
<node CREATED="1789485959655" ID="ID_1357089333" MODIFIED="1789518269807" TEXT="oder mit einem Offset knapp unter dem Limit"/>
<node COLOR="#5b280f" CREATED="1789485980355" ID="ID_1975112618" MODIFIED="1789525168334" TEXT="man k&#xf6;nnte zeigen da&#xdf; die Berechnung ungenau wird &#xfc;ber dem Limit">
<icon BUILTIN="button_cancel"/>
<node CREATED="1789486105659" ID="ID_1422733682" MODIFIED="1789486116438" TEXT="f&#xfc;r maxVal &gt; Limit"/>
<node CREATED="1789486117635" ID="ID_1961938709" MODIFIED="1789486122240" TEXT="aber auch f&#xfc;r zu gro&#xdf;e Domain"/>
</node>
<node COLOR="#5b280f" CREATED="1789485994791" ID="ID_1294711924" MODIFIED="1789525135527" TEXT="man k&#xf6;nnte eine Domain-Gr&#xf6;&#xdf;e am Limit testen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
die sollte dann aber nur f&#252;r Input-Werte unterhalb des Limits funktionieren, allerdings auch negative Werte; oberhalb des Limits w&#252;rde ich Entgleisungen vermuten
</p>
</body>
</html></richcontent>
<icon BUILTIN="button_cancel"/>
<node CREATED="1789525137057" ID="ID_188158552" MODIFIED="1789525146844" TEXT="nein: l&#xe4;&#xdf;t sich nicht sinnvoll im Test demonstrieren"/>
<node CREATED="1789525147624" ID="ID_888819868" MODIFIED="1789525160044" TEXT="(ich sehe die Entgleisungen wenn ich mir die Zahlen im Debugger anschaue)"/>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1789486294164" ID="ID_712679325" MODIFIED="1789517587212" TEXT="Beobachtungen: genau am Limit funktioniert das einfache Beispiel noch">
<icon BUILTIN="broken-line"/>
<node CREATED="1789486311768" ID="ID_204301662" MODIFIED="1789486325968" TEXT="ein Epsilon drunter wird absorbiert"/>
<node BACKGROUND_COLOR="#cab2bd" COLOR="#980009" CREATED="1789486326998" ID="ID_185831565" MODIFIED="1789517613464" TEXT="m&#xfc;&#xdf;te also tats&#xe4;chlich ein ULP daneben gehen">
<icon BUILTIN="idea"/>
</node>
<node CREATED="1789517621465" ID="ID_1146256096" MODIFIED="1789517635375" TEXT="tats&#xe4;chlich: das Stepping wird unzuverl&#xe4;ssig"/>
<node CREATED="1789517696551" ID="ID_825633898" MODIFIED="1789517744461" TEXT="limit &#xb7; &#x3b5; &#x2261; &#xbd; periode">
<node CREATED="1789517760503" ID="ID_205743420" MODIFIED="1789517788314" TEXT="das haben wir aber genau so definiert...">
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1789517771893" ID="ID_624480094" MODIFIED="1789517791174" TEXT="insofern ist das kein &#xbb;Test&#xab;">
<icon BUILTIN="stop-sign"/>
<node CREATED="1789517806226" ID="ID_1031466232" MODIFIED="1789517811675" TEXT="ein Test sollte Verhalten zeigen"/>
<node CREATED="1789517812425" ID="ID_1660313139" MODIFIED="1789517821515" TEXT="und nicht eine Definition replizieren"/>
</node>
</node>
</node>
<node CREATED="1789518828341" ID="ID_452450374" MODIFIED="1789525394621">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
Problem ist: hier kann ich kein &#187;<b>korrekt</b>&#171; oder &#187;<b>defekt</b>&#171; zeigen
</p>
</body>
</html></richcontent>
<linktarget COLOR="#57fec0" DESTINATION="ID_452450374" ENDARROW="Default" ENDINCLINATION="-182;8;" ID="Arrow_ID_1586349868" SOURCE="ID_409017691" STARTARROW="None" STARTINCLINATION="87;8;"/>
<icon BUILTIN="broken-line"/>
<node CREATED="1789518866588" ID="ID_1949224608" MODIFIED="1789518885765" TEXT="das Verhalten wird zum Limit hin zunehmend &#xbb;unscharf&#xab;"/>
<node CREATED="1789518886522" ID="ID_515488673" MODIFIED="1789518921574" TEXT="wie viel Unsch&#xe4;rfe tolerierbar ist l&#xe4;&#xdf;t sich nicht generisch sagen">
<node CREATED="1789518978509" ID="ID_1991175199" MODIFIED="1789518986039" TEXT="es gibt keine &#xbb;Schrittweite&#xab;"/>
<node CREATED="1789518987204" ID="ID_30471047" MODIFIED="1789519013068" TEXT="wann ist ein &quot;off by 0.1&#xab; noch tolerierbar??"/>
</node>
<node CREATED="1789518902636" ID="ID_1841879477" MODIFIED="1789518930946" TEXT="letztlich sind floating-point-numbers immer &#xbb;unscharf&#xab;"/>
<node CREATED="1789518945761" ID="ID_1474263016" MODIFIED="1789518957882" TEXT="jedwede Demonstration w&#xfc;rde eben nur dieses darstellen"/>
<node BACKGROUND_COLOR="#f7dba2" COLOR="#690f14" CREATED="1789522669935" ID="ID_1829288235" MODIFIED="1789522703291" TEXT="und : eine klar verst&#xe4;ndliche Demonstration ist schwer">
<icon BUILTIN="messagebox_warning"/>
<node COLOR="#b21478" CREATED="1789522720139" ID="ID_1872531495" MODIFIED="1789522906208" TEXT="Grenzwerte sind &#xbb;unhandlich&#xab;">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
sobald man mit &#949; und ULPs hantiert, sind die numerischen Werte nur so minuti&#246;s verschieden, da&#223; man es in der &#252;blichen, gerundeten Darstellung gar nicht sieht. Damit scheiden alle Test-Methoden aus, die &quot;einfache Zahlen&quot; verwenden und ein festes Ergebnis vorgeben. Hinzu kommt, da&#223; man auch einen &#949;-Vergleich machen mu&#223;, und dann ohne gesonderte &#220;berlegung nicht offensichtlich ist, welche &quot;Unsch&#228;rfe&quot; nun &quot;unscharf&quot; ist, und welche Teil des Test-Subjekts ist. Nicht da&#223; man das alles irgendwie &quot;hinbekommt&quot; &#8212; aber der Leser versteht nicht mehr, <i>was hier gespielt wird.</i>
</p>
</body>
</html></richcontent>
<font NAME="SansSerif" SIZE="11"/>
<icon BUILTIN="smily_bad"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1789521749900" ID="ID_912513687" MODIFIED="1789525194850" TEXT="sollte aber trotzdem wesentliche Elemente demonstrieren">
<icon BUILTIN="yes"/>
<node CREATED="1789521771353" ID="ID_559262092" MODIFIED="1789522935600" TEXT="was das &#xbb;limit&#xab; bedeutet : n&#xe4;mlich im Verh&#xe4;ltnis zur Periode"/>
<node CREATED="1789521783888" ID="ID_1660128606" MODIFIED="1789521817663" TEXT="da&#xdf; das Wrapping mit einem sehr gro&#xdf;en Intervall funktioniert"/>
<node CREATED="1789521818763" ID="ID_22678032" MODIFIED="1789521843436" TEXT="da&#xdf; es nahe der Interval-Obergrenze zu einem Aliasing kommen kann"/>
</node>
<node BACKGROUND_COLOR="#a6fdce" COLOR="#338800" CREATED="1789521853775" ID="ID_1420946197" MODIFIED="1789525101636" TEXT="Test formulieren...">
<icon BUILTIN="yes"/>
<node CREATED="1789521897465" ID="ID_1330009757" MODIFIED="1789521904636" TEXT="zun&#xe4;chst alles f&#xfc;r double"/>
<node CREATED="1789521905359" ID="ID_284924920" MODIFIED="1789521995911" TEXT="aber bereits mit Konversionen und almostEqual"/>
<node CREATED="1789525027288" ID="ID_1906103710" MODIFIED="1789525036691" TEXT="dann auf generischen Float umstellen...">
<node CREATED="1789525037796" ID="ID_767684162" MODIFIED="1789525039283" TEXT="float"/>
<node CREATED="1789525040023" ID="ID_1224952753" MODIFIED="1789525041834" TEXT="double"/>
<node CREATED="1789525042606" ID="ID_815586095" MODIFIED="1789525045834" TEXT="long double"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#174956" COLOR="#8dfd49" CREATED="1788313090668" HGAP="15" ID="ID_904924646" MODIFIED="1789525281531" STYLE="bubble" TEXT="ufff: GR&#xdc;N" VSHIFT="2">
<edge COLOR="#61fe5b" STYLE="bezier" WIDTH="thin"/>
<icon BUILTIN="ksmiletris"/>
<node COLOR="#0f3e46" CREATED="1789525285095" HGAP="36" ID="ID_409017691" MODIFIED="1789525404221" STYLE="fork" TEXT="das ist schon &#xbb;advanced stuff&#xab;...." VSHIFT="-10">
<arrowlink COLOR="#57fec0" DESTINATION="ID_452450374" ENDARROW="Default" ENDINCLINATION="-182;8;" ID="Arrow_ID_1586349868" STARTARROW="None" STARTINCLINATION="87;8;"/>
<font NAME="SansSerif" SIZE="10"/>
</node>
</node>
</node>
<node CREATED="1789313641938" ID="ID_1271083241" MODIFIED="1789313655675" TEXT="man k&#xf6;nnte aber auch versuchen, an eine generische Library-funktion zu delegieren"/>
</node>
</node>
<node COLOR="#338800" CREATED="1789171888403" ID="ID_1422919144" MODIFIED="1789171908101" TEXT="min/max clamp">