<commit_before>﻿// Copyright (c) Narvalo.Org. All rights reserved. See LICENSE.txt in the project root for license information.

namespace Narvalo.Finance
{
    using System;
    using System.Diagnostics.CodeAnalysis;

    // Adapt the operators found in the class Math.
    public static partial class MoneyMath
    {
        public static Money Abs(Money money) => money.IsPositiveOrZero ? money : money.Negate();

        public static int Sign(Money money) => money.Amount < 0m ? -1 : (money.Amount > 0m ? 1 : 0);

        public static Money Max(Money money1, Money money2) => money1 >= money2 ? money1 : money2;

        public static Money Min(Money money1, Money money2) => money1 <= money2 ? money1 : money2;

        public static Money Clamp(Money money, Money min, Money max)
        {
            Require.True(min <= max, nameof(min));

            return money < min ? min : (money > max ? max : money);
        }

        // Divide+Remainder aka DivRem.
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Div", Justification = "[Intentionally] Math.DivRem().")]
        [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "[Intentionally] Math.DivRem().")]
        public static Money DivRem(Money dividend, decimal divisor, out Money remainder)
        {
            // REVIEW: remainder = dividend % divisor is slower for integers. What about decimals?
            // > var q = dividend.Divide(divisor);
            // > remainder = dividend.Remainder(divisor);
            // For doubles, .NET uses:
            // > Modulus = (Math.Abs(dividend) - (Math.Abs(divisor)
            // >   * (Math.Floor(Math.Abs(dividend) / Math.Abs(divisor)))))
            // >   * Math.Sign(dividend)
            decimal q = dividend.Amount / divisor;
            decimal rem = dividend.Amount - q * divisor;
            remainder = new Money(rem, dividend.Currency);
            return new Money(q, dividend.Currency);
        }
    }

    public static partial class MoneyMath
    {
        public static decimal Ceiling(Money money) => Round(money, Math.Ceiling);

        public static decimal Floor(Money money) => Round(money, Math.Floor);

        public static decimal Truncate(Money money) => Round(money, Math.Truncate);

        public static decimal Round(Money money) => Round(money, Math.Round);

        public static decimal Round(Money money, MidpointRounding mode)
            => Round(money, _ => Math.Round(_, mode));

        public static decimal Round(Money money, int decimalPlaces)
            => Round(money, decimalPlaces, MidpointRounding.ToEven);

        public static decimal Round(Money money, int decimalPlaces, MidpointRounding mode)
        {
            // If the amount is already rounded to decimalPlaces, do nothing.
            if (money.IsNormalized && money.Currency.DecimalPlaces == decimalPlaces) { return money.Amount; }
            return Math.Round(money.Amount, decimalPlaces, mode);
        }

        private static decimal Round(Money money, Func<decimal, decimal> thunk)
        {
            Demand.NotNull(thunk);
            // If the amount is already rounded to 0, do nothing.
            if (money.IsNormalized && money.Currency.DecimalPlaces == 0) { return money.Amount; }
            return thunk.Invoke(money.Amount);
        }
    }
}<commit_msg>Fix: replace call to IsNormalized by IsRounded.<commit_after>﻿// Copyright (c) Narvalo.Org. All rights reserved. See LICENSE.txt in the project root for license information.

namespace Narvalo.Finance
{
    using System;
    using System.Diagnostics.CodeAnalysis;

    // Adapt the operators found in the class Math.
    public static partial class MoneyMath
    {
        public static Money Abs(Money money) => money.IsPositiveOrZero ? money : money.Negate();

        public static int Sign(Money money) => money.Amount < 0m ? -1 : (money.Amount > 0m ? 1 : 0);

        public static Money Max(Money money1, Money money2) => money1 >= money2 ? money1 : money2;

        public static Money Min(Money money1, Money money2) => money1 <= money2 ? money1 : money2;

        public static Money Clamp(Money money, Money min, Money max)
        {
            Require.True(min <= max, nameof(min));

            return money < min ? min : (money > max ? max : money);
        }

        // Divide+Remainder aka DivRem.
        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Div", Justification = "[Intentionally] Math.DivRem().")]
        [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "[Intentionally] Math.DivRem().")]
        public static Money DivRem(Money dividend, decimal divisor, out Money remainder)
        {
            // REVIEW: remainder = dividend % divisor is slower for integers. What about decimals?
            // > var q = dividend.Divide(divisor);
            // > remainder = dividend.Remainder(divisor);
            // For doubles, .NET uses:
            // > Modulus = (Math.Abs(dividend) - (Math.Abs(divisor)
            // >   * (Math.Floor(Math.Abs(dividend) / Math.Abs(divisor)))))
            // >   * Math.Sign(dividend)
            decimal q = dividend.Amount / divisor;
            decimal rem = dividend.Amount - q * divisor;
            remainder = new Money(rem, dividend.Currency);
            return new Money(q, dividend.Currency);
        }
    }

    public static partial class MoneyMath
    {
        public static decimal Ceiling(Money money) => Round(money, Math.Ceiling);

        public static decimal Floor(Money money) => Round(money, Math.Floor);

        public static decimal Truncate(Money money) => Round(money, Math.Truncate);

        public static decimal Round(Money money) => Round(money, Math.Round);

        public static decimal Round(Money money, MidpointRounding mode)
            => Round(money, _ => Math.Round(_, mode));

        public static decimal Round(Money money, int decimalPlaces)
            => Round(money, decimalPlaces, MidpointRounding.ToEven);

        public static decimal Round(Money money, int decimalPlaces, MidpointRounding mode)
        {
            // If the amount is already rounded to decimalPlaces, do nothing.
            if (money.IsRounded && money.Currency.DecimalPlaces == decimalPlaces) { return money.Amount; }
            return Math.Round(money.Amount, decimalPlaces, mode);
        }

        private static decimal Round(Money money, Func<decimal, decimal> thunk)
        {
            Demand.NotNull(thunk);
            // If the amount is already rounded to 0, do nothing.
            if (money.IsRounded && money.Currency.DecimalPlaces == 0) { return money.Amount; }
            return thunk.Invoke(money.Amount);
        }
    }
}
{'fraction_non_alphanumeric': 0.10861313868613139, 'fraction_numerical': 0.008175182481751826, 'mean_word_length': 2.5169404517453797, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4532217', 'n_tokens_mistral': 1980, 'n_tokens_neox': 1842, 'n_words': 558}