diff options
author | hamish-rose <hamishr@protonmail.com> | 2019-02-12 23:56:00 +1300 |
---|---|---|
committer | Tanner Gooding <tagoo@outlook.com> | 2019-02-12 02:56:00 -0800 |
commit | 3397472200fc7b2b5db3dfd27a652a12831c37ee (patch) | |
tree | 59ccf8c5a8dd3713284b1a81de529a9855eb65e2 /src/System.Private.CoreLib/shared/System/Math.cs | |
parent | 37d3388d394a305151901720e13a7bd45eb8ca90 (diff) | |
download | coreclr-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.cs | 52 |
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; } |