Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scale decimal value by a power of 10

Tags:

.net

decimal

What is the best way to scale a System.Decimal value by a power of 10 when the number of places is known?

value * (decimal)Math.Pow(10, places) comes to mind, but it suffers from two disadvantages:

  1. It introduces floating point, which makes round-off errors difficult to reason about as the numbers get big.

  2. It seems like overkill to do exponentiation when all you're trying to do is change the simple scale component already encoded in the decimal data structure.

Is there is a better way?

like image 636
Edward Brey Avatar asked May 02 '17 19:05

Edward Brey


1 Answers

You could create a table of powers of 10's like:

var pow10s = new int [] { 1, 10, 100, 1000, 10000, 100000, ... };

And then use places as an index into this table:

return value * pow10s[place]

Update: If you don't want the thing to crash when you attempt to index the array past N places, you could take a slightly more sophisticated approach, like so:

public class Power10Scale
{
    private static readonly int[] Pow10s = {
        1, 10, 100, 1000, 10000, 100000,
    };

    public static int Up(int value, int places)
    {
        return Scale(value, places, (x, y) => x * y);
    }

    public static int Down(int value, int places)
    {
        return Scale(value, places, (x, y) => x / y);
    }

    private static int Scale(int value, int places, Func<int, int, int> operation)
    {
        if (places < Pow10s.Length)
            return operation(value, Pow10s[places]);

        return Scale(
            operation(value, Pow10s[Pow10s.Length - 1]),
            places - (Pow10s.Length - 1),
            operation);
    }
}
like image 119
rtlayzell Avatar answered Oct 01 '22 05:10

rtlayzell