Implement System.Decimal.Scale (#66403)
authorMichalPetryka <35800402+MichalPetryka@users.noreply.github.com>
Thu, 10 Mar 2022 03:26:36 +0000 (04:26 +0100)
committerGitHub <noreply@github.com>
Thu, 10 Mar 2022 03:26:36 +0000 (20:26 -0700)
Adds System.Decimal.Scale, a property that
returns the scaling factor of the decimal.

Closes #65074.

src/libraries/System.Private.CoreLib/src/System/Decimal.DecCalc.cs
src/libraries/System.Private.CoreLib/src/System/Decimal.cs
src/libraries/System.Runtime/ref/System.Runtime.cs
src/libraries/System.Runtime/tests/System/DecimalTests.cs

index 57754d3..349c8fd 100644 (file)
@@ -19,8 +19,6 @@ namespace System
 
         internal bool IsNegative => _flags < 0;
 
-        internal int Scale => (byte)(_flags >> ScaleShift);
-
         private ulong Low64 => _lo64;
 
         private static ref DecCalc AsMutable(ref decimal d) => ref Unsafe.As<decimal, DecCalc>(ref d);
index 41a58c6..290a0c7 100644 (file)
@@ -326,6 +326,11 @@ namespace System
             _flags = flags;
         }
 
+        /// <summary>
+        /// Gets the scaling factor of the decimal, which is a number from 0 to 28 that represents the number of decimal digits.
+        /// </summary>
+        public byte Scale => (byte)(_flags >> ScaleShift);
+
         // Returns the absolute value of the given Decimal. If d is
         // positive, the result is d. If d is negative, the result
         // is -d.
index 72a2646..923c402 100644 (file)
@@ -2085,6 +2085,7 @@ namespace System
         public Decimal(uint value) { throw null; }
         [System.CLSCompliantAttribute(false)]
         public Decimal(ulong value) { throw null; }
+        public byte Scale { get { throw null; } }
         public static System.Decimal Add(System.Decimal d1, System.Decimal d2) { throw null; }
         public static System.Decimal Ceiling(System.Decimal d) { throw null; }
         public static int Compare(System.Decimal d1, System.Decimal d2) { throw null; }
index 84f585c..13c93da 100644 (file)
@@ -257,6 +257,37 @@ namespace System.Tests
             AssertExtensions.Throws<ArgumentOutOfRangeException>("scale", () => new Decimal(1, 2, 3, false, 29));
         }
 
+        public static IEnumerable<object[]> Scale_TestData()
+        {
+            yield return new object[] { 10m, 0 };
+            yield return new object[] { 1m, 0 };
+            yield return new object[] { -1m, 0 };
+            yield return new object[] { 1.0m, 1 };
+            yield return new object[] { -1.0m, 1 };
+            yield return new object[] { 1.1m, 1 };
+            yield return new object[] { 1.00m, 2 };
+            yield return new object[] { 1.01m, 2 };
+            yield return new object[] { 1.0000000000000000000000000000m, 28};
+        }
+
+        [Theory]
+        [MemberData(nameof(Scale_TestData))]
+        public static void Scale(decimal value, byte expectedScale)
+        {
+            Assert.Equal(expectedScale, value.Scale);
+        }
+
+        [Theory]
+        [InlineData(new int[] { 1, 0, 0, 0 }, 0)] // 1
+        [InlineData(new int[] { 10, 0, 0, 65536 }, 1)] // 1.0
+        [InlineData(new int[] { 100, 0, 0, 131072 }, 2)] // 1.00
+        [InlineData(new int[] { 268435456, 1042612833, 542101086, 1835008 }, 28)] // 1.0000000000000000000000000000
+        [InlineData(new int[] { 10, 0, 0, -2147418112 }, 1)] // -1.0
+        public static void ScaleFromBits(int[] bits, byte expectedScale)
+        {
+            Assert.Equal(expectedScale, new decimal(bits).Scale);
+        }
+
         public static IEnumerable<object[]> Add_Valid_TestData()
         {
             yield return new object[] { 1m, 1m, 2m };
@@ -968,7 +999,7 @@ namespace System.Tests
                 Assert.Equal(0, result);
             }
         }
-        
+
         public static IEnumerable<object[]> Remainder_Valid_TestData()
         {
             decimal NegativeZero = new decimal(0, 0, 0, true, 0);