예제 #1
0
        public static Money18 Truncate(
            Money18 value)
        {
            var significand = value._significand / Pow10(value._scale);

            return(new Money18(significand, 0));
        }
예제 #2
0
        private static (BigInteger, BigInteger) EqualizeSignificands(
            Money18 left,
            Money18 right)
        {
            if (left._scale == right._scale)
            {
                return(left._significand, right._significand);
            }

            var leftExponent  = 0;
            var rightExponent = 0;

            if (left._scale > right._scale)
            {
                rightExponent = left._scale - right._scale;
            }
            else
            {
                leftExponent = right._scale - left._scale;
            }

            var leftSignificand  = left._significand * Pow10(leftExponent);
            var rightSignificand = right._significand * Pow10(rightExponent);

            return(leftSignificand, rightSignificand);
        }
예제 #3
0
        public static Money18 Create(
            decimal value,
            int accuracy)
        {
            var(significand, scale) = value.GetSignificandAndScale();
            var money = new Money18(significand, scale);

            return(scale == accuracy ? money : Round(money, accuracy));
        }
예제 #4
0
        public static Money18 Round(
            Money18 value,
            int scale,
            MidpointRounding mode)
        {
            var significand = RoundSignificand(value._significand, value._scale, scale, mode);

            return(new Money18(significand, scale));
        }
예제 #5
0
        public static Money18 Add(
            Money18 left,
            Money18 right)
        {
            var(leftSignificand, rightSignificand) = EqualizeSignificands(left, right);
            var sumSignificand = leftSignificand + rightSignificand;
            var sumScale       = Math.Max(left._scale, right._scale);

            return(new Money18(sumSignificand, sumScale));
        }
예제 #6
0
        public static Money18 Subtract(
            Money18 left,
            Money18 right)
        {
            var(leftSignificand, rightSignificand) = EqualizeSignificands(left, right);
            var diffSignificand = leftSignificand - rightSignificand;
            var diffScale       = Math.Max(left._scale, right._scale);

            return(new Money18(diffSignificand, diffScale));
        }
예제 #7
0
 public static Money18 Abs(
     Money18 value)
 {
     if (value < 0)
     {
         return(-value);
     }
     else
     {
         return(value);
     }
 }
예제 #8
0
        public static Money18 Multiply(
            Money18 left,
            Money18 right)
        {
            var(leftSignificand, rightSignificand) = EqualizeSignificands(left, right);
            var productScale       = Math.Max(left._scale, right._scale);
            var productSignificand = RoundSignificand
                                     (
                significand: leftSignificand * rightSignificand,
                significandScale: productScale * 2,
                scale: productScale,
                mode: DefaultRoundingMode
                                     );

            return(new Money18(productSignificand, productScale));
        }
예제 #9
0
        public static Money18 Divide(
            Money18 left,
            Money18 right)
        {
            if (right == 0)
            {
                throw new DivideByZeroException();
            }

            var(leftSignificand, rightSignificand) = EqualizeSignificands(left, right);
            var quotientScale = Math.Max(left._scale, right._scale);

            var quotientSignificand = RoundSignificand
                                      (
                significand: leftSignificand * Pow10(quotientScale * 2) / rightSignificand,
                significandScale: quotientScale * 2,
                scale: quotientScale,
                mode: DefaultRoundingMode
                                      );

            return(new Money18(quotientSignificand, quotientScale));
        }
예제 #10
0
        public static bool TryParse(
            string value,
            out Money18 result)
        {
            if (value != null && MoneyFormat.IsMatch(value))
            {
                var decimalAndFractionalParts = value.Split('.');

                // ReSharper disable once SwitchStatementMissingSomeCases
                switch (decimalAndFractionalParts.Length)
                {
                case 1:
                {
                    var significand = BigInteger.Parse(value);

                    result = new Money18(significand, 0);

                    return(true);
                }

                case 2:
                {
                    value = string.Concat(decimalAndFractionalParts);

                    var significand = BigInteger.Parse(value);
                    var scale       = decimalAndFractionalParts[1].Length;

                    result = new Money18(significand, scale);

                    return(true);
                }
                }
            }

            result = default;

            return(false);
        }
예제 #11
0
        public static Money18 Ceiling(
            Money18 value)
        {
            if (value == 0)
            {
                return(value);
            }

            var significand = BigInteger.DivRem
                              (
                dividend: value._significand,
                divisor: Pow10(value._scale),
                remainder: out var remainder
                              );

            if (remainder != 0 && value > 0)
            {
                significand++;
            }

            significand *= Pow10(value._scale);

            return(new Money18(significand, value._scale));
        }
예제 #12
0
 public static Money18 Round(
     Money18 value,
     int scale)
 {
     return(Round(value, scale, DefaultRoundingMode));
 }
예제 #13
0
 public static Money18 Round(
     Money18 value,
     MidpointRounding mode)
 {
     return(Round(value, 0, mode));
 }
예제 #14
0
 public static Money18 Round(
     Money18 value)
 {
     return(Round(value, 0, DefaultRoundingMode));
 }
예제 #15
0
 public static Money18 Negate(
     Money18 value)
 {
     return(new Money18(-value._significand, value._scale));
 }