Пример #1
0
        public Money Round(RoundingPlaces places, MidpointRoundingRule rounding, out Money remainder)
        {
            Int64 unit;

            var placesExponent = getExponentFromPlaces(places);
            var fraction       = roundFraction(placesExponent, rounding, out unit);
            var units          = _units + unit;

            remainder = new Money(0, _decimalFraction - fraction, Asset);

            return(new Money(units, fraction, Asset));
        }
Пример #2
0
        private Int32 roundFraction(Int32 exponent, MidpointRoundingRule rounding, out Int64 unit)
        {
            var denominator = FractionScale / (Decimal)Math.Pow(10, exponent);
            var fraction    = _decimalFraction / denominator;

            switch (rounding)
            {
            case MidpointRoundingRule.ToEven:
                fraction = Math.Round(fraction, MidpointRounding.ToEven);
                break;

            case MidpointRoundingRule.AwayFromZero:
            {
                var sign = Math.Sign(fraction);
                fraction  = Math.Abs(fraction);              // make positive
                fraction  = Math.Floor(fraction + 0.5M);     // round UP
                fraction *= sign;                            // reapply sign
                break;
            }

            case MidpointRoundingRule.TowardZero:
            {
                var sign = Math.Sign(fraction);
                fraction  = Math.Abs(fraction);              // make positive
                fraction  = Math.Floor(fraction + 0.5M);     // round DOWN
                fraction *= sign;                            // reapply sign
                break;
            }

            case MidpointRoundingRule.Up:
                fraction = Math.Floor(fraction + 0.5M);
                break;

            case MidpointRoundingRule.Down:
                fraction = Math.Ceiling(fraction - 0.5M);
                break;

            case MidpointRoundingRule.Stochastic:
                if (_rng == null)
                {
                    _rng = new MersenneTwister();
                }

                var coinFlip = _rng.NextDouble();

                if (coinFlip >= 0.5)
                {
                    goto case MidpointRoundingRule.Up;
                }

                goto case MidpointRoundingRule.Down;

            default:
                throw new ArgumentOutOfRangeException("rounding");
            }

            fraction *= denominator;

            if (fraction >= FractionScale)
            {
                unit     = 1;
                fraction = fraction - (Int32)FractionScale;
            }
            else
            {
                unit = 0;
            }

            return((Int32)fraction);
        }
Пример #3
0
        public Money Round(RoundingPlaces places, MidpointRoundingRule rounding = MidpointRoundingRule.ToEven)
        {
            Money remainder;

            return(Round(places, rounding, out remainder));
        }