Truncate a Number to Given Decimal Points

I need to truncate the number to two decimal places, which basically means reducing extra digits.

For instance:

2.919 -> 2.91 2.91111 -> 2.91 

Why? This is what SQL Server does when storing a few extra precision. For example, if the column is Decimal (8.2) and you are trying to insert / update the number 9.1234, 3 and 4 will be chopped off.

I need to do the same in C # code.

The only possible ways that I can think of are either:

  • Using stringformatter to β€œprint” only two decimal places, and then converting it to decimal, for example:

      decimal tooManyDigits = 2.1345 decimal ShorterDigits = Convert.ToDecimal(tooManyDigits.ToString("0.##")); // ShorterDigits is now 2.13 

    I am not happy with this because it includes a string, and then another string to decimal conversion, which seems a little crazy.

  • Using Math.Truncate (which only accepts an integer), so I can multiply it by 100, truncate it, and then divide by 100. For example:

     decimal tooLongDecimal = 2.1235; tooLongDecimal = Math.Truncate(tooLongDecimal * 100) / 100; 

    I am also not happy with this, because if tooLongDecimal is 0, I will get a division error by 0.

Of course there is a better + easier way! Any suggestions?

+6
source share
4 answers

You yourself answered the question; It seems you just did not understand what division by zero means. The correct way to do this is to multiply, truncate, and then divide, like this:

 decimal TruncateTo100ths(decimal d) { return Math.Truncate(d* 100) / 100; } TruncateTo100ths(0m); // 0 TruncateTo100ths(2.919m); // 2.91 TruncateTo100ths(2.91111m); // 2.91 TruncateTo100ths(2.1345m); // 2.13 

There is no division by zero, there is only division by 100, which is completely safe.

+5
source

Previously proposed mathematical solutions are vulnerable to overflow with large numbers and / or a large number of decimal places. Instead, consider the following extension:

 [System.Runtime.CompilerServices.Extension()] public static decimal TruncateDecimal(decimal d, int decimals) { if (decimals < 0) throw new ArgumentOutOfRangeException("decimals", "Value must be in range 0-28."); else if (decimals > 28) throw new ArgumentOutOfRangeException("decimals", "Value must be in range 0-28."); else if (decimals = 0) return Math.Truncate(d); else { decimal integerPart = Math.Truncate(d); decimal scalingFactor = d - integerPart; decimal multiplier = Math.Pow(10, decimals); scalingFactor = Math.Truncate(scalingFactor * multiplier) / multiplier; return integerPart + scalingFactor; } } 

Using:

 decimal value = 18446744073709551615.262626263m; value = value.TruncateDecimal(6); 
+3
source

I agree with pswg. I had a similar requirement, and here is my experience and a more generalized truncation function.

http://snathani.blogspot.com/2014/05/truncating-number-to-specificnumber-of.html

 public static decimal Truncate(decimal value, int decimals) { decimal factor = (decimal)Math.Pow(10, decimals); decimal result = Math.Truncate(factor * value) / factor; return result; } 
+1
source

Using decimal.ToString('0.##') also causes rounding:

 1.119M.ToString("0.##") // -> 1.12 

(Yes, most likely, this is a comment, but it is difficult to format it as such.)

0
source

Source: https://habr.com/ru/post/949425/


All Articles