2009-06-30 13 views
6

, =ROUNDUP(474.872126666666, 2)는 - 474.88 .NET에서
,엑셀 라운드 업 Excel에서

Math.Round(474.87212666666666666666666666667, 2, MidpointRounding.ToEven) // 474.87 
Math.Round(474.87212666666666666666666666667, 2, MidpointRounding.AwayFromZero) // 474.87 

내 클라이언트가 Excel에서 반올림 원하는 결과는, 내가 .NET에서 474.88을 얻을 수있는 방법이>가 무엇입니까?

덕분에 많은

답변

16
double ROUNDUP(double number, int digits) 
    { 
    return Math.Ceiling(number * Math.Pow(10, digits))/Math.Pow(10, digits); 
    } 
+0

이 솔루션은 행복의 흐름을 아주 잘 커버합니다. 불행히도 음수에 대해서는 올바르게 작동하지 않을 것이고, 음수의 숫자 (지원되는 Excel)에서는 올바르게 작동하지 않을 것이고 "숫자"가 Double.Max와 같은 큰 값에 접근 할 때 올바르게 작동하지 않을 것입니다. 큰 가치이며 범위를 벗어날 것입니다. –

1

Math.Ceiling은 당신이 찾고있는 것입니다.

+2

참고 이 함수로 소수점 수를 지정할 수 없으므로 OP는 Math.Ceiling을 수행하기 전에 100을 곱한 다음 100으로 나눕니다. –

+0

Math.Ceiling (474.87212666666666666666666666667)은 내가 원하는 것이 아닌 475를 반환합니다. – nandin

+3

수학. 화학 (474.8721266666666666666666666666767 * 100)/100 작품. 감사합니다 둘 다 – nandin

0

여기에 Excel 둘러보기 기능처럼 작동하는 해결책이 있습니다. 네거티브 진수 음 자리 (네 엑셀 것을 지원하는) 큰 소수 값

여기
public static decimal RoundUp(decimal number, int digits) 
{ 
    if (digits > 0) 
    { 
     // numbers will have a format like +/-1.23, where the fractional part is optional if numbers are integral 
     // Excel RoundUp rounds negative numbers as if they were positive. 
     // To simulate this behavior we will use the absolute value of the number 
     // E.g. |1.23| = |-1.23| = 1.23 
     var absNumber = Math.Abs(number); 

     // Now take the integral part (E.g. for 1.23 is 1) 
     var absNumberIntegralPart = Decimal.Floor(absNumber); 

     // Now take the fractional part (E.g. for 1.23 is 0.23) 
     var fraction = (absNumber - absNumberIntegralPart); 

     // Multiply fractional part by the 10^number of digits we're rounding to 
     // E.g. For 1.23 with rounded to 1 digit it will be 0.23 * 10^1 = 2.3 
     // Then we round that value UP using Decimal.Ceiling and we transform it back to a fractional part by dividing it by 10^number of digits 
     // E.g. Decimal.Ceiling(0.23 * 10)/10 = Decimal.Ceiling(2.3)/10 = 3/10 = 0.3 
     var tenPower = (decimal)Math.Pow(10, digits); 
     var fractionRoundedUp = Decimal.Ceiling(fraction * tenPower)/tenPower; 

     // Now we add up the absolute part with the rounded up fractional part and we put back the negative sign if needed 
     // E.g. 1 + 0.3 = 1.3 
     return Math.Sign(number) * (absNumberIntegralPart + fractionRoundedUp); 
    } else if (digits == 0) 
    { 
     return Math.Sign(number) * Decimal.Ceiling(Math.Abs(number)); 
    } else if (digits < 0) 
    { 
     // negative digit rounding means that for RoundUp(149.12, -2) we will discard the fractional part, shift the decimal point on the left part 2 places before rounding up 
     // then replace all digits on the right of the decimal point with zeroes 
     // E.g. RoundUp(149.12, -2). Shift decimal point 2 places => 1.49. Now roundup(1.49) = 2 and we put 00 instead of 49 => 200 

     var absNumber = Math.Abs(number); 
     var absNumberIntegralPart = Decimal.Floor(absNumber); 
     var tenPower = (decimal)Math.Pow(10, -digits); 
     var absNumberIntegraPartRoundedUp = Decimal.Ceiling(absNumberIntegralPart/tenPower) * tenPower; 
     return Math.Sign(number)*absNumberIntegraPartRoundedUp; 
    } 

    return number; 
} 

     [TestMethod] 
     public void Can_RoundUp_Correctly() 
     { 
      Assert.AreEqual(1.466m, MathExtensions.RoundUp(1.4655m, 3)); 
      Assert.AreEqual(-1.466m, MathExtensions.RoundUp(-1.4655m, 3)); 
      Assert.AreEqual(150m, MathExtensions.RoundUp(149.001m, 0)); 
      Assert.AreEqual(-150m, MathExtensions.RoundUp(-149.001m, 0)); 
      Assert.AreEqual(149.2m, MathExtensions.RoundUp(149.12m, 1)); 
      Assert.AreEqual(149.12m, MathExtensions.RoundUp(149.12m, 2)); 
      Assert.AreEqual(1232m, MathExtensions.RoundUp(1232, 2)); 
      Assert.AreEqual(200m, MathExtensions.RoundUp(149.123m, -2)); 
      Assert.AreEqual(-200m, MathExtensions.RoundUp(-149.123m, -2)); 
      Assert.AreEqual(-20m, MathExtensions.RoundUp(-12.4655m, -1)); 
      Assert.AreEqual(1.67m, MathExtensions.RoundUp(1.666666666666666666666666666m, 2)); 
      Assert.AreEqual(1000000000000000000000000000m, MathExtensions.RoundUp(999999999999999999999999999m, -2)); 
      Assert.AreEqual(10000000000000m, MathExtensions.RoundUp(9999999999999.999m, 2)); 
     } 
0

를 모집하고 ROUNDDOWN 대한 정확한 계산이다 : I와 같은 경우를 커버하려

private static object RoundDown(List<Expression> p) 
{ 
    var target = (decimal)p[0].Evaluate(); 
    var digits = (decimal)p[1].Evaluate(); 

    if (target < 0) return (Math.Ceiling((double)target * Math.Pow(10, (int)digits))/Math.Pow(10, (int)digits)); 

    return Math.Floor((double)target * Math.Pow(10, (int)digits))/Math.Pow(10, (int)digits); 
} 

private static object RoundUp(List<Expression> p) 
{ 
    var target = (decimal)p[0].Evaluate(); 
    var digits = (decimal)p[1].Evaluate(); 

    if (target < 0) return (Math.Floor((double)target * Math.Pow(10, (int)digits))/Math.Pow(10, (int)digits)); 
    return Math.Ceiling((double)target * Math.Pow(10, (int)digits))/Math.Pow(10, (int)digits); 
}