Original: "C #" Excel Rounding function round, RoundUp, RoundDown C # version

In C # I often miss the round in Excel, RoundUp, RoundDown These functions, the reason is the latter "Earth gas", compared to the rounding requirements of my small people, what "banker rounding law" let the bankers use it. Today is free, it realized a bit, first review these several functions of Excel function:

**Round (value, digits)**

The value is rounded by rounding, the digits decimal is retained, and when digits is negative, rounding is done to the left of the decimal point, and when value is negative, the performance is the exact opposite of a positive number.

**Example:** Round (3.145, 2) = 3.15;round ( -3.145, 2) = -3.15;round (3145,-2) = 3100

**RoundUp (value, digits)**

Rounds value upward by a distance of 0, retains digits decimal places, and rounds to the left of the decimal when digits is negative

**Example:** RoundUp (3.111, 2) = 3.12;roundup ( -3.111, 2) = -3.12;roundup (3111,-2) = 3200

**RoundDown (value, digits)**

Rounds value down in the direction near 0, retains digits decimal places, and rounds to the left of the decimal when digits is negative

**Example:** RoundDown (3.145, 2) = 3.14;rounddown ( -3.145, 2) = -3.14;rounddown (3145,-2) = 3100

**Implementation principle:**

-For Roundup and RoundDown, because the ceiling and floor methods of the decimal or math class (C/F) can only be rounded, the new value of the multiplication method is obtained based on the number of bits to be retained, and then the c/f can be used to get the rounded value , and then multiply/divide back to get the final result. This method is common in the market.

**Example:**1.114 2 bits up, first 1.114x100 get 111.4, then C (111.4) to get 112, then 112/100, finally get 1.12

**problem:** because the original value is to be multiplication first, so for near Max/min, or high accuracy of the original value, this step will cause overflow, so up and down can not deal with a particularly large value, but the daily application believe that no problem.

-For the Roundex method, the decimal is encapsulated directly. Round (decimal, Midpointrounding.awayfromzero) gets the result.

**Implementation notes:**

-Provided as an extension method, compatible with general method invocation (nonsense). Can be 3.145m.roundex (2) or Mathex.roundex (3.145M, 2)

-Each method provides overloads with two types of decimal and double, a total of 6 methods

-The implementation is based on the decimal type, and the double version is just a reuse + type conversion. The reason that double is not implemented is not because of laziness, but because floating-point arithmetic is easy to pull eggs, such as 555.55x100=55554.999999999993. For non-reliability of floating-point arithmetic, see: http://www.cnblogs.com/ethancai/articles/1237012.html

-The rounding function is named Roundex because the decimal class already has a static method called Round, and if it is not staggered, it cannot be called in extended Mode 3m.round (). And although. NET has a great degree of inclusion in naming, I think it's best to avoid the FCL naming and to "enjoy" this freedom.

-Several methods have to first determine the number of reserved digits, and not directly using the 10 digits to perform the operation, is to try to follow the decimal type of native methods, reduce unnecessary mathematical operations. What we're after is not minimalist code, but performance. Of course, not tested ~ eggs fly in ...

A bunch of crap, on the code:

/// <summary>///Mathematical class extension methods/// </summary> Public Static classmathex{/// <summary> ///away from 0 rounding up/// </summary> Public Static decimalRoundUp ( This decimalValuesbytedigits) { if(Digits = =0) { return(Value >=0?decimal. Ceiling (value):decimal. Floor (value)); } decimalmultiple = Convert.todecimal (Math.pow (Ten, digits)); return(Value >=0?decimal. Ceiling (Value * multiple):decimal. Floor (value * multiple))/multiple; } /// <summary> ///near 0 rounding down/// </summary> Public Static decimalRoundDown ( This decimalValuesbytedigits) { if(Digits = =0) { return(Value >=0?decimal. Floor (value):decimal. Ceiling (value)); } decimalmultiple = Convert.todecimal (Math.pow (Ten, digits)); return(Value >=0?decimal. Floor (Value * multiple):decimal. Ceiling (value * multiple))/multiple; } /// <summary> ///Rounding/// </summary> Public Static decimalRoundex ( This decimalValuesbytedigits) { if(Digits >=0) { return decimal. Round (value, digits, Midpointrounding.awayfromzero); } decimalmultiple = Convert.todecimal (Math.pow (Ten, -digits)); return decimal. Round (Value/multiple, Midpointrounding.awayfromzero) *multiple; } /// <summary> ///away from 0 rounding up/// </summary> Public Static DoubleRoundUp ( This DoubleValuesbytedigits) { return decimal. ToDouble (Convert.todecimal (value). RoundUp (digits)); } /// <summary> ///near 0 rounding down/// </summary> Public Static DoubleRoundDown ( This DoubleValuesbytedigits) { return decimal. ToDouble (Convert.todecimal (value). RoundDown (digits)); } /// <summary> ///Rounding/// </summary> Public Static DoubleRoundex ( This DoubleValuesbytedigits) { return decimal. ToDouble (Convert.todecimal (value). Roundex (digits)); }}

**-Wenbi-**

"C #" Excel Rounding functions round, RoundUp, RoundDown C # version