-3

Here is situation:

Input:

var a = 1.2567789m;
var b = 1.898436216m;
var c = 1.79863m;

var aD = 2;
var bD = 3;
var cD = 1;

Result:

var aR = 1.25m;  
var bR = 1.898m;
var cR = 1.7m;

So input is different decimal numbers with different amounts of decimal places and number of need decimal numbers. I need to round down input numbers by the number of decimal places, which can be different every time. I wrote a method for this which is working fine, but I wonder if there is a better solution :

    static void Main(string[] args)
            {
                var a = 1.2567789m;
                var b = 1.898436216m;
                var c = 1.79863m;
    
                var aD = 2;
                var bD = 3;
                var cD = 1;
    
                Console.WriteLine(RoundDown(a, aD));
                Console.WriteLine(RoundDown(b, bD));
                Console.WriteLine(RoundDown(c, cD));
                Console.ReadLine();
            }
    
            private static decimal RoundDown(decimal number, int decimals)
            {
                switch (decimals)
                {
                    case 1:
                    {
                        return (Math.Truncate(number * 10)) / 10;
                    }
                    case 2:
                    {
                        return Math.Truncate(number * 100) / 100;
                    }
                    case 3:
                    {
                        return Math.Truncate(number * 1000) / 1000;
                    }
                    case 4:
                    {
                        return Math.Truncate(number * 10000) / 10000;
                    }
                    case 5:
                    {
                        return Math.Truncate(number * 100000) / 100000;
                    }
                    case 6:
                    {
                        return Math.Truncate(number * 1000000) / 1000000;
                    }
                    case 7:
                    {
                        return (Math.Truncate(number * 10000000)) / 10000000;
                    }
                    case 8:
                    {
                        return Math.Truncate(number * 100000000) / 100000000;
                    }
                    case 9:
                    {
                        return Math.Truncate(number * 1000000000) / 1000000000;
                    }
                    case 10:
                    {
                        return Math.Truncate(number * 10000000000) / 10000000000;
                    }
                    default: return 0;
                }
            }

Thank you very much in advance

3 Answers3

1

You can compute 10 ** digits in a loop; then scale, compute Floor and scale back:

Code:

private static decimal MyFloor(decimal value, int digits = 0) {
  decimal power = 1;
        
  for (int i = 0; i < digits; ++i)
    power = digits >= 0 ? power * 10 : power / 10;

  return Math.Floor(value * power) / power;
}

Demo:

var tests = new (decimal value, int digits)[] {
  (1.2567789m, 2),
  (1.898436216m, 3),
  (1.79863m, 1)
};

string report = string.Join(Environment.NewLine, tests
  .Select(test => $"Floor({test.value}, {test.digits}) = {MyFloor(test.value, test.digits)}"));

Console.WriteLine(report);

Outcome:

Floor(1.2567789, 2) = 1.25
Floor(1.898436216, 3) = 1.898
Floor(1.79863, 1) = 1.7
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
1

these all u need

Math.Round()
Math.Floor()
Math.Ceiling()
Jason N
  • 109
  • 3
0

While Dimitry's answer as usual excellent Math.Round is the tool for the job:

foreach( var x in new [] {( V: 1.2567789m, D: 2),(V: 1.898436216m, D: 3),(V: 1.79863m, D: 1)})
    Console.WriteLine($"{x.V} @ {x.D} = {Math.Round(x.V, x.D, MidpointRounding.ToZero)}");

This produces:

1.2567789 @ 2 = 1.25
1.898436216 @ 3 = 1.898
1.79863 @ 1 = 1.7
tymtam
  • 31,798
  • 8
  • 86
  • 126