BlackWaspTM
C# Programming
.NET 2.0+

Rounding Decimal Values in C#

The decimal data type is used to store numbers with a high level of precision. The potentially large number of decimal places held is useful for many mathematical or statistical calculations. However, it is helpful to round values for display purposes.

Rounding Values

C# provides three native numeric data types for holding floating point values. These are the single-precision, double-precision and decimal numbers, which are declared using the "float", "double" and "decimal" keywords respectively. Each of these types holds a different range of possible values with varying levels of precision. The "float" type is the least precise with the smallest range of values and the "decimal" type has the largest range and greatest precision. The selection of the type of value to use for any purpose is a trade-off between the size and accuracy requirements of the numbers being held and the amount of memory used by a declared variable.

In this article we will be working with the decimal data type, not for its size or precision but for the additional functionality provided by this type over the other two options. Specifically, we will be using the four static rounding methods that are only available to decimal values. Of course, you can round single and double-precision numbers too. However, in these cases you must first cast or convert the value to a decimal first or use members of the Math class.

NB: The methods described in this article require the .NET framework version 2.0 or later. Some of the functions are available in .NET 1.1 but there use may be limited.

Truncation

One of the most basic ways to round a decimal is truncation. With truncation, all fractional digits are simply removed from the number leaving only the integer part, though still held in a decimal. This can be easily demonstrated using the following code. Note how the decimal part is removed and the values are rounded downwards to the nearest integer for the first two lines. In the third line, the value remains unchanged, as there is no fractional part. In the last two lines, the negative values are effectively rounded upwards.

decimal result;
result = decimal.Truncate(1.2M);    // result = 1
result = decimal.Truncate(1.9M);    // result = 1
result = decimal.Truncate(1M);      // result = 1
result = decimal.Truncate(-1.2M);   // result = -1
result = decimal.Truncate(-1.9M);   // result = -1

Floor and Ceiling

The static Floor and Ceiling methods perform similar functions to truncation, in that they remove the decimal portion of the number and return an integer. Again the integer is returned within a decimal structure. The key difference between these methods and truncation is that the direction of rounding is fixed for both positive and negative numbers. For the floor function the rounding is always downwards and for ceiling it is always upwards, as can be seen in the results of the sample code below.

decimal result;
result = decimal.Floor(1.2M);       // result = 1
result = decimal.Floor(1.9M);       // result = 1
result = decimal.Floor(1M);         // result = 1
result = decimal.Floor(-1.2M);      // result = -2
result = decimal.Floor(-1.9M);      // result = -2

result = decimal.Ceiling(1.2M);     // result = 2
result = decimal.Ceiling(1.9M);     // result = 2
result = decimal.Ceiling(1M);       // result = 1
result = decimal.Ceiling(-1.2M);    // result = -1
result = decimal.Ceiling(-1.9M);    // result = -1
16 November 2008