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/MathF.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/MathF.cs')
-rw-r--r-- | src/System.Private.CoreLib/shared/System/MathF.cs | 54 |
1 files changed, 43 insertions, 11 deletions
diff --git a/src/System.Private.CoreLib/shared/System/MathF.cs b/src/System.Private.CoreLib/shared/System/MathF.cs index 3bff55daeb..1defa4e40b 100644 --- a/src/System.Private.CoreLib/shared/System/MathF.cs +++ b/src/System.Private.CoreLib/shared/System/MathF.cs @@ -306,9 +306,9 @@ 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_InvalidEnum, mode, nameof(MidpointRounding)), nameof(mode)); + throw new ArgumentException(SR.Format(SR.Argument_InvalidEnumValue, mode, nameof(MidpointRounding)), nameof(mode)); } if (Abs(x) < singleRoundLimit) @@ -317,20 +317,52 @@ namespace System x *= power10; - if (mode == MidpointRounding.AwayFromZero) + switch (mode) { - var fraction = ModF(x, &x); + // 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: + { + x = Round(x); + 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: + { + float fraction = ModF(x, &x); + + if (Abs(fraction) >= 0.5) + { + x += Sign(fraction); + } - if (Abs(fraction) >= 0.5f) + break; + } + // Directed rounding: Round to the nearest value, toward to zero + case MidpointRounding.ToZero: { - x += Sign(fraction); + x = Truncate(x); + break; + } + // Directed Rounding: Round down to the next value, toward negative infinity + case MidpointRounding.ToNegativeInfinity: + { + x = Floor(x); + break; + } + // Directed rounding: Round up to the next value, toward positive infinity + case MidpointRounding.ToPositiveInfinity: + { + x = Ceiling(x); + break; + } + default: + { + throw new ArgumentException(SR.Format(SR.Argument_InvalidEnumValue, mode, nameof(MidpointRounding)), nameof(mode)); } } - else - { - x = Round(x); - } - + x /= power10; } |