summaryrefslogtreecommitdiff
path: root/src/System.Private.CoreLib/shared/System/Math.cs
diff options
context:
space:
mode:
authorhamish-rose <hamishr@protonmail.com>2019-02-12 23:56:00 +1300
committerTanner Gooding <tagoo@outlook.com>2019-02-12 02:56:00 -0800
commit3397472200fc7b2b5db3dfd27a652a12831c37ee (patch)
tree59ccf8c5a8dd3713284b1a81de529a9855eb65e2 /src/System.Private.CoreLib/shared/System/Math.cs
parent37d3388d394a305151901720e13a7bd45eb8ca90 (diff)
downloadcoreclr-3397472200fc7b2b5db3dfd27a652a12831c37ee.tar.gz
coreclr-3397472200fc7b2b5db3dfd27a652a12831c37ee.tar.bz2
coreclr-3397472200fc7b2b5db3dfd27a652a12831c37ee.zip
Add new rounding modes to System.Math, System.MathF (#20815)
* add new rounding modes to MidpointRounding.cs new modes added to enum implemented ToZero for double in Math.cs * ToZero implementation * implement double and float rounding modes * updating rounding implementation now round inline with DecCalc internal round implementation * small bug fix also replace var to make things obvious * update implementation - floor/ceil code review feedback * review feedback add comments, update MathF with floor/ceil * code review feedback - fix comments - replace ifelse with switch - remove RoundingMode enum from DecCalc * exclude outdated corefx test
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/Math.cs')
-rw-r--r--src/System.Private.CoreLib/shared/System/Math.cs52
1 files changed, 42 insertions, 10 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Math.cs b/src/System.Private.CoreLib/shared/System/Math.cs
index af74185a88..1c36c9d230 100644
--- a/src/System.Private.CoreLib/shared/System/Math.cs
+++ b/src/System.Private.CoreLib/shared/System/Math.cs
@@ -892,7 +892,7 @@ namespace System
throw new ArgumentOutOfRangeException(nameof(digits), SR.ArgumentOutOfRange_RoundingDigits);
}
- if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero)
+ if (mode < MidpointRounding.ToEven || mode > MidpointRounding.ToPositiveInfinity)
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidEnumValue, mode, nameof(MidpointRounding)), nameof(mode));
}
@@ -903,20 +903,52 @@ namespace System
value *= power10;
- if (mode == MidpointRounding.AwayFromZero)
+ switch (mode)
{
- var fraction = ModF(value, &value);
+ // Rounds to the nearest value; if the number falls midway,
+ // it is rounded to the nearest value with an even least significant digit
+ case MidpointRounding.ToEven:
+ {
+ value = Round(value);
+ break;
+ }
+ // Rounds to the nearest value; if the number falls midway,
+ // it is rounded to the nearest value above (for positive numbers) or below (for negative numbers)
+ case MidpointRounding.AwayFromZero:
+ {
+ double fraction = ModF(value, &value);
+
+ if (Abs(fraction) >= 0.5)
+ {
+ value += Sign(fraction);
+ }
- if (Abs(fraction) >= 0.5)
+ break;
+ }
+ // Directed rounding: Round to the nearest value, toward to zero
+ case MidpointRounding.ToZero:
{
- value += Sign(fraction);
+ value = Truncate(value);
+ break;
+ }
+ // Directed Rounding: Round down to the next value, toward negative infinity
+ case MidpointRounding.ToNegativeInfinity:
+ {
+ value = Floor(value);
+ break;
+ }
+ // Directed rounding: Round up to the next value, toward positive infinity
+ case MidpointRounding.ToPositiveInfinity:
+ {
+ value = Ceiling(value);
+ break;
+ }
+ default:
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidEnumValue, mode, nameof(MidpointRounding)), nameof(mode));
}
}
- else
- {
- value = Round(value);
- }
-
+
value /= power10;
}