4

upd placed my version in the description at the end

I need to convert mantissa and exponent to decimal. This is how I coded that:

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

field.Decimal.Mantissa is integer but Math.Pow(10, field.Decimal.Exponent) is double so I afraid that I can lost precision when casting to decimal.

Should I write my own Pow function for integer types that will produce decimal?

What would you suggest? I care about perfomance as I call this functions dozen of thousands times per second! So ugly but fast solutions are highly desired!

And I care about precision as I'm working with money here.

This is what I've just coded, but probably someone can suggest something better:

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;
    }
}
svick
  • 236,525
  • 50
  • 385
  • 514
Oleg Vazhnev
  • 23,239
  • 54
  • 171
  • 305
  • Did you look at this [SO question](http://stackoverflow.com/questions/429165/raising-a-decimal-to-a-power-of-decimal) and especially [this answer](http://stackoverflow.com/a/5425527/452274)? – Matt Apr 03 '12 at 12:41
  • @Matt Yes I did, It seems it will not work for negative integer exponents... however it's easy to modify to support negative exponent. but note my question is much easier. I don't need to raise decimal in power of decimal. I need to raise long in power of sbyte! So I work with integers. And I expect that probably some simple solution exist (probably using low-level instructions like << or something else....) – Oleg Vazhnev Apr 03 '12 at 12:53

1 Answers1

1

There is a constructor of decimal that does pretty much what you want. But it uses the internal representation of decimal, which is different from your representation. The conversion should be pretty simple for numbers with negative exponent, since you can directly translate that into the scale parameter of the constructor. But with positive exponent, I think you will need to do the multiplication by yourself.

Although I have no idea whether it would be actually faster than your code. And it would be certainly much less readable, so your solution might be fine.

svick
  • 236,525
  • 50
  • 385
  • 514
  • i think my example from description would be more intuitive and probably even a little bit faster. – Oleg Vazhnev Apr 03 '12 at 13:56
  • You're saying you care about performance. In that case, you should profile various versions of your code, not just guess. – svick Apr 03 '12 at 13:57
  • I don't care that much. I prefer to have perfomance when it easy. I will profile only when perfomance problem would be obvious or I will have too much free time :) – Oleg Vazhnev Apr 03 '12 at 15:02