|
12 | 12 | // See the License for the specific language governing permissions and |
13 | 13 | // limitations under the License. |
14 | 14 |
|
15 | | -using System; |
16 | | - |
17 | 15 | namespace OnixLabs.Playground; |
18 | 16 |
|
19 | 17 | internal static class Program |
20 | 18 | { |
21 | 19 | private static void Main() |
22 | 20 | { |
23 | | - decimal value = 100.13m; |
24 | | - decimal round = value.SetScale(2); |
25 | | - |
26 | | - Console.WriteLine(round); |
27 | | - } |
28 | | - |
29 | | - public static decimal SetScale(this decimal value, int scale) |
30 | | - { |
31 | | - Require(scale >= 0, "Scale must be greater than, or equal to zero."); |
32 | | - |
33 | | - // Count actual decimal places |
34 | | - int actualScale = GetDecimalPlaces(value); |
35 | | - |
36 | | - if (actualScale == scale) |
37 | | - { |
38 | | - return value; |
39 | | - } |
40 | | - |
41 | | - if (actualScale < scale) |
42 | | - { |
43 | | - // Pad with zeroes by scaling and descaling |
44 | | - decimal factor = Pow10(scale - actualScale); |
45 | | - return value * factor / factor; |
46 | | - } |
47 | | - |
48 | | - else // actualScale > scale |
49 | | - { |
50 | | - // Check if the digits beyond the desired scale are zero |
51 | | - decimal factor = Pow10(actualScale - scale); |
52 | | - decimal remainder = (value * factor) % 1; |
53 | | - |
54 | | - if (remainder != 0) |
55 | | - throw new InvalidOperationException($"Cannot reduce scale without losing precision: {value}"); |
56 | | - |
57 | | - return Math.Truncate(value * Pow10(scale)) / Pow10(scale); |
58 | | - } |
59 | | - } |
60 | | - |
61 | | - private static int GetDecimalPlaces(decimal value) |
62 | | - { |
63 | | - int[] bits = decimal.GetBits(value); |
64 | | - byte scale = (byte)((bits[3] >> 16) & 0x7F); |
65 | | - return scale; |
66 | | - } |
67 | | - |
68 | | - private static decimal Pow10(int exp) |
69 | | - { |
70 | | - decimal result = 1m; |
71 | | - for (int i = 0; i < exp; i++) |
72 | | - result *= 10; |
73 | | - return result; |
74 | 21 | } |
75 | 22 | } |
0 commit comments