Преобразовать (длинная мантисса) и (показатель степени sbyte) в десятичную

upd разместил мою версию в описании в конце

Мне нужно перевести мантиссу и экспоненту в десятичную. Вот как я кодировал это:

// long field.Decimal.Mantissa
// sbyte field.Decimal.Exponent
decimal MDEntryPx = field.Decimal.Mantissa * (decimal)(Math.Pow(10, field.Decimal.Exponent));

field.Decimal.Mantissa целое число, но Math.Pow(10, field.Decimal.Exponent) удваивается, поэтому я боюсь, что могу потерять точность при приведении к десятичной дроби.

Должен ли я написать свой собственный Pow функция для integer типы, которые будут производить decimal?

Что ты предлагаешь? Я забочусь о производительности, так как я вызываю эти функции десятки тысяч раз в секунду! Настолько уродливые, но быстрые решения очень желательны!

И я забочусь о точности, так как я работаю с деньгами здесь.

Это то, что я только что написал, но, возможно, кто-то может предложить что-то лучше:

class Util
{
    private static readonly decimal[] posPow10 = {
                                           1M,
                                           10M,
                                           100M,
                                           1000M,
                                           10000M,
                                           100000M,
                                           1000000M,
                                           10000000M,
                                           100000000M,
                                           1000000000M,
                                           10000000000M,
                                           100000000000M
                                       };

    private static readonly decimal[] negPow10 = {
                                           1M,
                                           0.1M,
                                           0.01M,
                                           0.001M,
                                           0.0001M,
                                           0.00001M,
                                           0.000001M,
                                           0.0000001M,
                                           0.00000001M,
                                           0.000000001M,
                                           0.0000000001M,
                                           0.00000000001M,
                                       };


    public static decimal Pow(decimal mantissa, sbyte exponent)
    {
        decimal result = mantissa;
        if (exponent >= 0)
        {
            result *= posPow10[exponent];
        } else {
            result *= negPow10[-exponent];
        }
        return result;
    }
}

1 ответ

Есть конструкторdecimal это делает в значительной степени то, что вы хотите. Но он использует внутреннее представление decimal, который отличается от вашего представления. Преобразование должно быть довольно простым для чисел с отрицательным exponent, так как вы можете напрямую перевести это в scale параметр конструктора. Но с положительным exponentЯ думаю, вам нужно будет сделать умножение самостоятельно.

Хотя я понятия не имею, будет ли это на самом деле быстрее, чем ваш код. И это, безусловно, будет гораздо менее читабельным, поэтому ваше решение может быть в порядке.

Другие вопросы по тегам