From 2e7bd9b4b97ff35fd07889992995a489726baaa3 Mon Sep 17 00:00:00 2001 From: mkr7 Date: Wed, 8 Apr 2020 11:35:36 +0200 Subject: [PATCH 1/6] Add function to round to nearest integer --- Modelica/Math/nearestInteger.mo | 50 +++++++++++++++++++++++++++++++++ Modelica/Math/package.order | 1 + 2 files changed, 51 insertions(+) create mode 100644 Modelica/Math/nearestInteger.mo diff --git a/Modelica/Math/nearestInteger.mo b/Modelica/Math/nearestInteger.mo new file mode 100644 index 0000000000..6c5050c9e6 --- /dev/null +++ b/Modelica/Math/nearestInteger.mo @@ -0,0 +1,50 @@ +within Modelica.Math; +function nearestInteger "Convert real number to nearest integer value" + extends Modelica.Icons.Function; + + input Real r "Real number to convert to integer"; + output Integer i "Integer value, which is closest to the given real number"; + +algorithm + i :=if (r > 0) then integer(floor(r + 0.5)) else integer(ceil(r - 0.5)); + + annotation (Documentation(info=" + +

Syntax

+
+Math.nearestInteger(r);
+
+ +

Description

+

+ The input value \"r\" of type Real is converted to the closest Integer value \"i\", + using the round half away from zero rule with the equation: +

+
+i = integer( floor( r + 0.5 ) )  for  r > 0;
+i = integer(  ceil( r - 0.5 ) )  for  r < 0;
+
+ +

Example

+
+import Modelica.Math;
+Math.nearestInteger(0.4);                     // = 0
+Math.nearestInteger(0.5);                     // = 1
+Math.nearestInteger(-0.4);                    // = 0
+Math.nearestInteger(-0.5);                    // = -1
+Math.nearestInteger(0.3999999999999999+0.1);  // = 0
+Math.nearestInteger(1.39999999999999999+0.1); // = 1 (errorneous border case, see note below)
+
+ +

Note

+ +

+ This function does the same conversion as the block + RealToInteger. +

+

+ The underlying equation is simple, but not always correct. Due to floating point arithmetic some border cases + are not converted correct, like shown in the example above. +

+")); +end nearestInteger; diff --git a/Modelica/Math/package.order b/Modelica/Math/package.order index c1f671ddc0..2e18c9335a 100644 --- a/Modelica/Math/package.order +++ b/Modelica/Math/package.order @@ -10,6 +10,7 @@ FastFourierTransform Icons isEqual isPowerOf2 +nearestInteger sin cos tan From 2748168ee363ee6784e756a72bffe4e3b045da7f Mon Sep 17 00:00:00 2001 From: mkr7 Date: Wed, 15 Apr 2020 12:31:11 +0200 Subject: [PATCH 2/6] Add tests for nearestInteger --- ModelicaTest/Math.mo | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ModelicaTest/Math.mo b/ModelicaTest/Math.mo index 26d07b7cc9..38e3dcfd34 100644 --- a/ModelicaTest/Math.mo +++ b/ModelicaTest/Math.mo @@ -32,6 +32,14 @@ extends Modelica.Icons.ExamplesPackage; assert(Math.isPowerOf2(1), "isPowerOf2(1) is wrong"); assert(Math.isPowerOf2(4), "isPowerOf2(4) is wrong"); assert(not Math.isPowerOf2(9), "isPowerOf2(9) is wrong"); + + assert(Math.nearestInteger(1.4999)==1, "nearesetInteger(1.4999) failed"); + assert(Math.nearestInteger(1.5)==2, "nearesetInteger(1.5) failed"); + assert(Math.nearestInteger(-1.4999)==-1, "nearesetInteger(-1.4999) failed"); + assert(Math.nearestInteger(-1.5)==-2, "nearesetInteger(-1.5) failed"); + // Test deactivated - would fail with current implementation + // assert(Math.nearestInteger(1.49999999999999999999)==1, "nearestInteger border case failed"); + ok:=true; end ScalarFunctions; From 283c45ba148b8d1fd6dc254772a1a1ac854f1f15 Mon Sep 17 00:00:00 2001 From: Marco Kessler Date: Wed, 15 Apr 2020 13:33:06 +0200 Subject: [PATCH 3/6] Fix naming in nearestInteger tests Co-Authored-By: Thomas Beutlich --- ModelicaTest/Math.mo | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ModelicaTest/Math.mo b/ModelicaTest/Math.mo index 38e3dcfd34..df9d43d692 100644 --- a/ModelicaTest/Math.mo +++ b/ModelicaTest/Math.mo @@ -33,10 +33,10 @@ extends Modelica.Icons.ExamplesPackage; assert(Math.isPowerOf2(4), "isPowerOf2(4) is wrong"); assert(not Math.isPowerOf2(9), "isPowerOf2(9) is wrong"); - assert(Math.nearestInteger(1.4999)==1, "nearesetInteger(1.4999) failed"); - assert(Math.nearestInteger(1.5)==2, "nearesetInteger(1.5) failed"); - assert(Math.nearestInteger(-1.4999)==-1, "nearesetInteger(-1.4999) failed"); - assert(Math.nearestInteger(-1.5)==-2, "nearesetInteger(-1.5) failed"); + assert(Math.nearestInteger(1.4999)==1, "nearestInteger(1.4999) failed"); + assert(Math.nearestInteger(1.5)==2, "nearestInteger(1.5) failed"); + assert(Math.nearestInteger(-1.4999)==-1, "nearestInteger(-1.4999) failed"); + assert(Math.nearestInteger(-1.5)==-2, "nearestInteger(-1.5) failed"); // Test deactivated - would fail with current implementation // assert(Math.nearestInteger(1.49999999999999999999)==1, "nearestInteger border case failed"); From c1f191e2c8ebf855a12196f934d2ef185e41f7b6 Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Thu, 9 Apr 2020 23:08:01 +0200 Subject: [PATCH 4/6] Fix HTML tags and double quotes --- Modelica/Math/nearestInteger.mo | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modelica/Math/nearestInteger.mo b/Modelica/Math/nearestInteger.mo index 6c5050c9e6..21f2af987c 100644 --- a/Modelica/Math/nearestInteger.mo +++ b/Modelica/Math/nearestInteger.mo @@ -17,8 +17,8 @@ Math.nearestInteger(r);

Description

- The input value \"r\" of type Real is converted to the closest Integer value \"i\", - using the round half away from zero rule with the equation: + The input value \"r\" of type Real is converted to the closest Integer value \"i\", + using the round half away from zero rule with the equation:

 i = integer( floor( r + 0.5 ) )  for  r > 0;
@@ -33,7 +33,7 @@ Math.nearestInteger(0.5);                     // = 1
 Math.nearestInteger(-0.4);                    // = 0
 Math.nearestInteger(-0.5);                    // = -1
 Math.nearestInteger(0.3999999999999999+0.1);  // = 0
-Math.nearestInteger(1.39999999999999999+0.1); // = 1 (errorneous border case, see note below)
+Math.nearestInteger(1.39999999999999999+0.1); // = 1 (erroneous border case, see note below)
 

Note

From 7f9f10defa20de5829f12bbe3d7c6870e0317b0b Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Fri, 10 Apr 2020 14:08:01 +0200 Subject: [PATCH 5/6] Cosmetics: Remove indent --- Modelica/Math/nearestInteger.mo | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Modelica/Math/nearestInteger.mo b/Modelica/Math/nearestInteger.mo index 21f2af987c..8d9e9475b6 100644 --- a/Modelica/Math/nearestInteger.mo +++ b/Modelica/Math/nearestInteger.mo @@ -17,8 +17,8 @@ Math.nearestInteger(r);

Description

- The input value \"r\" of type Real is converted to the closest Integer value \"i\", - using the round half away from zero rule with the equation: +The input value \"r\" of type Real is converted to the closest Integer value \"i\", +using the round half away from zero rule with the equation:

 i = integer( floor( r + 0.5 ) )  for  r > 0;
@@ -39,12 +39,12 @@ Math.nearestInteger(1.39999999999999999+0.1); // = 1 (erroneous border case, see
 

Note

- This function does the same conversion as the block - RealToInteger. +This function does the same conversion as the block +RealToInteger.

- The underlying equation is simple, but not always correct. Due to floating point arithmetic some border cases - are not converted correct, like shown in the example above. +The underlying equation is simple, but not always correct. Due to floating point arithmetic some border cases +are not converted correct, like shown in the example above.

")); end nearestInteger; From 5c4e7080b1f6f92278aac95279fe0545bb70768f Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Thu, 29 Oct 2020 20:03:02 +0100 Subject: [PATCH 6/6] Remove documentation of border cases --- Modelica/Math/nearestInteger.mo | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Modelica/Math/nearestInteger.mo b/Modelica/Math/nearestInteger.mo index 8d9e9475b6..bda058567c 100644 --- a/Modelica/Math/nearestInteger.mo +++ b/Modelica/Math/nearestInteger.mo @@ -32,8 +32,6 @@ Math.nearestInteger(0.4); // = 0 Math.nearestInteger(0.5); // = 1 Math.nearestInteger(-0.4); // = 0 Math.nearestInteger(-0.5); // = -1 -Math.nearestInteger(0.3999999999999999+0.1); // = 0 -Math.nearestInteger(1.39999999999999999+0.1); // = 1 (erroneous border case, see note below)

Note

@@ -42,9 +40,5 @@ Math.nearestInteger(1.39999999999999999+0.1); // = 1 (erroneous border case, see This function does the same conversion as the block RealToInteger.

-

-The underlying equation is simple, but not always correct. Due to floating point arithmetic some border cases -are not converted correct, like shown in the example above. -

")); end nearestInteger;