diff --git a/tests/15library.tests b/tests/15library.tests index 74f985dc3..3b629393d 100644 --- a/tests/15library.tests +++ b/tests/15library.tests @@ -53,6 +53,11 @@ return: 0 END +TEST "Cyclic wrapping number domain" CyclicWrap_test < + +  **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" +#include "test/diagnostic-output.hpp"//////////////////TODO +//#include "lib/format-cout.hpp" +//#include "lib/format-string.hpp" + +using ::Test; +//using util::isnil; +//using util::_Fmt; +using util::isLimited; + + +namespace util { +namespace test { + + + + namespace{ // Test helpers... + + template + constexpr NUM _MAX = std::numeric_limits::max(); + + template + constexpr NUM _MIN = std::numeric_limits::lowest(); + + } // (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 + * @todo add coverage for floating-point numbers + * @see util::cyclicWrap + * @see parameter-scale-test.cpp + */ + class CyclicWrap_test : public Test + { + + virtual void + run (Arg) + { + simpleDemonstration(); + + verifyIntegerTypes(); + verifyIntegerTypes(); + verifyIntegerTypes(); + verifyIntegerTypes(); + verifyIntegerTypes (); + verifyIntegerTypes(); + verifyIntegerTypes (); + verifyIntegerTypes(); + verifyIntegerTypes (); + verifyIntegerTypes(); + } + + + 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 + void + verifyIntegerTypes () + { + const I LOWER(-100); // note: expected to wrap for unsigned types + const I UPPER(LOWER+5); + + auto cyc = [&](I val){ return cyclicWrap (I(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), UPPER)); + CHECK (isLimited (LOWER, cyc(_MIN), UPPER)); + + CHECK (isLimited (LOWER, cyc(_MAX-1), UPPER)); + CHECK (isLimited (LOWER, cyc(_MIN+1), UPPER)); + + I dist = LOWER - _MIN; // 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) ); + } + }; + + + + LAUNCHER (CyclicWrap_test, "unit common"); + + +}} // namespace util::test diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 9d26551c6..adbfa8b6b 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -86141,7 +86141,7 @@ class ScaleRegistry - + @@ -86158,7 +86158,8 @@ class ScaleRegistry

- + + @@ -86257,7 +86258,7 @@ class ScaleRegistry - + @@ -86337,7 +86338,7 @@ class ScaleRegistry - + @@ -86527,7 +86528,7 @@ class ScaleRegistry

- + @@ -86769,13 +86770,14 @@ Prop.1: dist%3 1 2 0 1 2 0

- + +
- + @@ -86784,7 +86786,7 @@ Prop.1: dist%3 1 2 0 1 2 0

- +
@@ -86806,13 +86808,14 @@ Prop.1: dist%3 1 2 0 1 2 0
- + +
- + @@ -86822,8 +86825,70 @@ Prop.1: dist%3 1 2 0 1 2 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ .... ich könnte mir denken, daß mancher Leser das Konzept nicht gleich versteht, deshalb ist ein solches einfaches Beispiel nie verkehrt +

+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + -