Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Truncating a number to specified decimal places

Tags:

c#

I need to truncate a number to 2 decimal places, which basically means chopping off the extra digits.

Eg:

2.919     ->      2.91

2.91111   ->     2.91

Why? This is what SQL server is doing when storing a number of a particular precision. Eg, if a column is Decimal(8,2), and you try to insert/update a number of 9.1234, the 3 and 4 will be chopped off.

I need to do exactly the same thing in c# code.

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

  1. Using the stringformatter to "print" it out only two decimal places, and then converting it to a decimal, eg:

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

    I'm not happy with this because it involves a to-string and then another string to decimal conversion which seems a bit mad.

  2. Using Math.Truncate (which only accepts an integer), so I can multiply it by 100, truncate it, then divide by 100. eg:

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

    I'm also not happy with this because if tooLongDecimal is 0, I'll get a divide by 0 error.

Surely there's a better + easier way! Any suggestions?

like image 377
roanjain Avatar asked Jul 14 '13 22:07

roanjain


People also ask

How do I truncate my decimal places?

The TRUNCATE() function truncates a number to the specified number of decimal places.

What does truncating a decimal mean?

In simplest terms, truncation means to chop off the decimal portion of a number. This means: Truncating 3.3 returns 3. Truncating 3.8 returns 3.

How do I truncate to two decimal places in Excel?

Select the cells that you want to format. On the Home tab, click Increase Decimal or Decrease Decimal to show more or fewer digits after the decimal point.

What is the difference between truncating and rounding?

In mathematics, rounding means rounding to the nearest integer, so rounding 3.4 results in 3 and rounding 3.6 results in 4. Truncating , on the other hand, means removing the fractional part altogether, so either 3.4 or 3.6 results in 3.


2 Answers

The previously offered mathematical solutions are vulnerable to overflow with large numbers and/or a large number of decimal places. Consider instead the following extension method:

public static decimal TruncateDecimal(this 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 = (decimal) Math.Pow(10, decimals);

        scalingFactor = Math.Truncate(scalingFactor * multiplier) / multiplier;

        return integerPart + scalingFactor;
    }
}

Usage:

decimal value = 18446744073709551615.262626263m;
value = value.TruncateDecimal(6); // Result: 18446744073709551615.262626
like image 121
MrGadget Avatar answered Sep 29 '22 18:09

MrGadget


I agree with p.s.w.g. I had the similar requirement and here is my experience and a more generalized function for truncating.

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;
}
like image 29
Sridhar Nathani Avatar answered Sep 29 '22 20:09

Sridhar Nathani