4

With Decimal.Round, I can only choose between ToEven and AwayFromZero, now I'd like to round it always to the smaller number, that is, like truncating, remove the digits that is out of the required decimals:

public static void Main()
{
    Console.WriteLine("{0,-10} {1,-10} {2,-10}", "Value", "ToEven", "AwayFromZero");
    for (decimal value = 12.123451m; value <= 12.123459m; value += 0.000001m)
        Console.WriteLine("{0} -- {1} -- {2}", value, Math.Round(value, 5, MidpointRounding.ToEven),
                       Math.Round(value, 5, MidpointRounding.AwayFromZero));
}

// output
12.123451 -- 12.12345 -- 12.12345
12.123452 -- 12.12345 -- 12.12345
12.123453 -- 12.12345 -- 12.12345
12.123454 -- 12.12345 -- 12.12345
12.123455 -- 12.12346 -- 12.12346
12.123456 -- 12.12346 -- 12.12346
12.123457 -- 12.12346 -- 12.12346
12.123458 -- 12.12346 -- 12.12346
12.123459 -- 12.12346 -- 12.12346

I just want all those to be rounded to 12.12345, that is keep 5 decimals, and truncating remaining ones. Is there a better way to do this?

fluter
  • 13,238
  • 8
  • 62
  • 100
  • Possible duplicate of [Truncate Two decimal places without rounding](https://stackoverflow.com/questions/3143657/truncate-two-decimal-places-without-rounding) – Mighty Badaboom Aug 07 '17 at 13:20

3 Answers3

5
decimal.Truncate(value * (decimal)Math.Pow(10, 5)) / (decimal)Math.Pow(10, 5);

or simply

decimal.Truncate(value * 100000) / 100000;

should solve your problem by shifting the value 5 digits left, truncating and shifting the 5 digits back.

Example in 4 steps:

  1. 1.23456 * 100000
  2. 12345.6 decimal.Truncate
  3. 12345 / 100000
  4. 1.2345

Not as much simple as the first approach but at least twice as fast at my device is using a string and split it. Here is my implementation:

string[] splitted = value.ToString(CultureInfo.InvariantCulture).Split('.');
string newDecimal = splitted[0];
if (splitted.Length > 1)
{
    newDecimal += ".";
    newDecimal += splitted[1].Substring(0, Math.Min(splitted[1].Length, 5));
}
decimal result = Convert.ToDecimal(newDecimal, CultureInfo.InvariantCulture);
Fruchtzwerg
  • 10,999
  • 12
  • 40
  • 49
1

You can use Math.Floor, if you modify the decimal places before you use it, and then return back to the original position like this:

public static decimal RoundDown(decimal input, int decimalPlaces)
{
    decimal power = (decimal) Math.Pow(10, decimalPlaces);
    return Math.Floor(input * power) / power;
}

Try it online!

0

Are you perhaps instead looking for Math.Floor?

Floor(Decimal) Returns the largest integer less than or equal to the specified decimal number.

Floor(Double) Returns the largest integer less than or equal to the specified double-precision floating-point number.

Community
  • 1
  • 1
TomServo
  • 7,248
  • 5
  • 30
  • 47
  • No, I'm not looking for Floor, I'm not for the nearest integer, rather nearest float point number with specified precision. – fluter Aug 07 '17 at 13:02