programing

왜 수학을 합니까?라운드(2.5)는 3 대신 2를 반환합니까?

muds 2023. 5. 26. 22:53
반응형

왜 수학을 합니까?라운드(2.5)는 3 대신 2를 반환합니까?

에서, C#의 결과는 다음과 같습니다.Math.Round(2.5)2입니다.

원래 3개죠?왜 C#에서 2가 아닌 거지?

첫째, 어쨌든 이것은 C# 버그가 아닐 것입니다 - 그것은 .NET 버그일 것입니다.입니다. C#이 쓰이는지는. 어떻게 할지 결정하지 않습니다.Math.Round구현됩니다.

둘째, 아니오 - 문서를 읽으면 기본 반올림이 "짝수 반올림"(은행가 반올림)임을 알 수 있습니다.


유형: 시스템.더블
가장 가까운 정수 a.의 분수 성분이 짝수와 홀수 중 하나인 두 정수 사이의 중간에 있으면 짝수가 반환됩니다.는 이메드다반니다합환음을는서▁a를 반환합니다.Double적분형 대신에

비고
표준 44항 IEEE 표준 754, 4항을 .이러한 종류의 라운딩은 때때로 가장 가까운 라운딩 또는 뱅커스 라운딩이라고 불립니다.중간점 값을 한 방향으로 일관되게 반올림함으로써 발생하는 반올림 오차를 최소화합니다.

방법을 지정할 수 있습니다.Math.Round값을 가져오는 오버로드를 사용하여 중간점을 반올림해야 합니다.과중한 일이 하나 있어요.MidpointRounding부하가 없는 각 과부하에 해당:

이 기본값이 잘 선택되었는지 여부는 다른 문제입니다.(MidpointRounding는 .NET 2.0에서만 도입되었습니다.그 이전에는 원하는 행동을 직접 수행하지 않고 구현할 수 있는 쉬운 방법이 있었는지 확신할 수 없습니다.)특히, 역사는 그것이 예상된 행동이 아니라는 것을 보여주었습니다 - 그리고 대부분의 경우 그것은 API 설계의 기본적인 죄악입니다.뱅커스 라운딩이 왜 유용한지 알겠어요하지만 여전히 많은 사람들에게 놀라운 일입니다.

더 많은 옵션을 제공하는 가장 가까운 Java 동등한 RoundingMode열거형()을 확인할 수 있습니다.(중간점만 다루는 것은 아닙니다.)

짝수 은행원)이라고 , 합 이 짝 또 반 이 올 은 누 오 합 최 를 류 적 소 화 하 의 기 위 반 전 유 한 니 입 략 림 올 다 한 효 이 계 는 를 림 반 올 며 하 수 가 림 는 행 고 라 ▁in ▁strategy ▁that ▁for ▁sums ▁( ▁rounding or ), ' ▁to ▁minim ▁even ▁valid izing 또 (MidpointRounding.ToEven)이 이론은 항상 같은 방향으로 0.5개의 숫자를 반올림하면 오차가 더 빨리 발생한다는 것입니다(반올림-짝수는 이를 최소화하도록 되어 있습니다).

MSDN에 대한 설명은 다음 링크를 따릅니다.

  • Math.Floor음의 무한대를 향해 반올림합니다.
  • Math.Ceiling양의 무한대를 향해 반올림합니다.
  • Math.Truncate0을 향해 위로 또는 아래로 반올림합니다.
  • Math.Round가장 가까운 정수 또는 지정된 소수 자릿수로 반올림합니다.마지막 자리가 짝수가 되도록 반올림하는 것과 같이 두 가능성 사이에 정확히 같은 거리에 있는 경우 동작을 지정할 수 있습니다("Round(2.5,MidpointRounding.ToEven)2) 또는 0에서 더 멀리 떨어져 있는 것("Round(2.5,MidpointRounding.AwayFromZero)이 되다, 3)이 되다.

다음 다이어그램과 표는 도움이 될 수 있습니다.

-3        -2        -1         0         1         2         3
 +--|------+---------+----|----+--|------+----|----+-------|-+
    a                     b       c           d            e

                       a=-2.7  b=-0.5  c=0.3  d=1.5  e=2.8
                       ======  ======  =====  =====  =====
Floor                    -3      -1      0      1      2
Ceiling                  -2       0      1      2      3
Truncate                 -2       0      0      1      2
Round(ToEven)            -3       0      0      2      3
Round(AwayFromZero)      -3      -1      0      2      3

:Round단순히 소수점 이하의 특정 숫자로 반올림할 수 있기 때문에 보이는 것보다 훨씬 강력합니다.다른 모든 것들은 소수점 이하 0점 이하로 반올림합니다.예:

n = 3.145;
a = System.Math.Round (n, 2, MidpointRounding.ToEven);       // 3.14
b = System.Math.Round (n, 2, MidpointRounding.AwayFromZero); // 3.15

다른 기능을 사용할 때는 곱셈/나눗셈 트릭을 사용해야 동일한 효과를 얻을 수 있습니다.

c = System.Math.Truncate (n * 100) / 100;                    // 3.14
d = System.Math.Ceiling (n * 100) / 100;                     // 3.15

(a) 물론 이 이론은 데이터가 짝수 반(0.5, 2.5, 4.5, ...)과 홀수 반(1.5, 3.5, ...)에 걸쳐 상당히 고른 분포의 값을 가지고 있다는 사실에 따라 달라집니다.

모든 "반값"이 짝수인 경우(예: 항상 반올림한 것처럼) 오류가 빠르게 누적됩니다.

MSDN에서 다음을 확인해야 합니다.

이 방법의 동작은 IEEE 표준 754, 섹션 4를 따릅니다.이러한 종류의 라운딩은 때때로 가장 가까운 라운딩 또는 뱅커스 라운딩이라고 불립니다.

의 동작을 할 수 .Math.Round오버로드 사용:

Math.Round(2.5, 0, MidpointRounding.AwayFromZero); // gives 3

Math.Round(2.5, 0, MidpointRounding.ToEven); // gives 2

MSDN, 수학에서.반올림(더블 a) 반환 수:

가장 가까운 정수 a.의 분수 성분이 짝수와 홀수 중 하나인 두 정수 사이의 중간에 있으면 짝수가 반환됩니다.

따라서 2와 3 사이의 중간인 2.5는 짝수 (2)로 반올림됩니다.이것은 뱅커스 라운딩(또는 반올림 대 짝수)이라고 하며, 일반적으로 사용되는 라운딩 표준입니다.

동일한 MSDN 문서:

이 방법의 동작은 IEEE 표준 754, 섹션 4를 따릅니다.이러한 종류의 라운딩은 때때로 가장 가까운 라운딩 또는 뱅커스 라운딩이라고 불립니다.중간점 값을 한 방향으로 일관되게 반올림함으로써 발생하는 반올림 오차를 최소화합니다.

연산의 오버로드를 호출하여 다른 반올림 동작을 지정할 수 있습니다.한 바퀴 돌면 됩니다.MidpointRoundingmode.mode.modice_1

반올림의 성질

분수를 포함하는 숫자를 정수로 반올림하는 작업을 고려합니다.이 경우 반올림하는 과정은 반올림하는 숫자를 가장 잘 나타내는 정수를 결정하는 것입니다.

일반적으로 2.1, 2.2, 2.3 및 2.4는 2.0으로 반올림하고 2.6, 2.7, 2.8 및 2.9 - 3.0으로 반올림합니다.

그것은 2.5를 남깁니다. 이것은 3.0보다 2.0에 가깝지 않습니다.2.0과 3.0 중 하나를 선택하는 것은 귀하에게 달려 있습니다. 둘 중 하나가 동일하게 유효합니다.

음수의 경우 -2.1, -2.2, -2.3 및 -2.4는 -2.0이 되고 산술 반올림을 통해 -2.6, 2.7, 2.8 및 2.9는 -3.0이 됩니다.

-2.5의 경우 -2.0과 -3.0 사이에서 선택해야 합니다.

반올림의 다른 형태

반올림'은 소수점 이하의 임의의 숫자를 사용하여 다음 '전체' 숫자로 만듭니다.따라서 2.5와 2.6은 3.0으로 반올림할 뿐만 아니라 2.1과 2.2도 마찬가지입니다.

반올림하면 양수와 음수가 모두 0에서 멀어집니다.예: 2.5 ~ 3.0 및 -2.5 ~ -3.0.

반올림'은 원치 않는 숫자를 잘라내어 숫자를 잘라냅니다.이는 숫자를 0으로 이동시키는 효과가 있습니다.예: 2.5 ~ 2.0 및 -2.5 ~ -2.0

"은행원 반올림"(가장 일반적인 형태)에서 반올림할 .5는 올림 결과가 항상 짝수가 되도록 위로 또는 아래로 반올림됩니다.따라서 2.5에서 2.0, 3.5에서 4.0, 4.5에서 4.0, 5.5에서 6.0 등으로 반올림합니다.

'대체 반올림'은 반올림과 반올림 사이의 0.5에 대한 공정을 번갈아 표시합니다.

'임의 반올림'은 완전히 임의로 .5를 위 또는 아래로 반올림합니다.

대칭과 비대칭

반올림 함수는 0에서 모든 숫자를 반올림하거나 0을 향해 모든 숫자를 반올림하는 경우 '대칭'이라고 합니다.

양수가 0을 향해 반올림하고 음수가 0에서 멀어지면 함수는 '비대칭'입니다.예: 2.5 ~ 2.0 및 -2.5 ~ -3.0.

또한 비대칭은 양수를 0에서 멀어지게 하고 음수를 0으로 반올림하는 함수입니다.예: 2.5 ~ 3.0 및 -2.5 ~ -2.0.

사람들은 대부분 대칭 반올림을 생각합니다. 여기서 -2.5는 -3.0을 향해 반올림하고 3.5는 4.0을 향해 반올림합니다. (C#)Round(AwayFromZero))

은 " " 입니다.MidpointRounding.ToEven또는 뱅커스 라운딩(2.5가 2, 4.5가 4 등)은 회계 보고서를 작성하는 것에 대해 전에 저를 괴롭혔기 때문에 이전에 알게 된 내용과 이 게시물을 조사하여 알게 된 내용을 몇 마디 쓰겠습니다.

짝수를 반올림하고 있는 이 은행가들은 누구입니까? (영국 은행가들은 아마도!)?

위키백과에서

은행가들의 반올림이라는 용어의 기원은 여전히 더 모호합니다.만약 이 반올림 방법이 은행 업무의 표준이었다면, 그 증거는 찾기가 매우 어려운 것으로 판명되었습니다.반대로, 유럽 위원회 보고서의 섹션 2는 유로의 도입과 통화량 반올림은 이전에 은행에서 반올림에 대한 표준 접근법이 없었다는 것을 시사합니다. 그리고 "중간" 금액을 반올림해야 한다고 명시합니다.

물론 은행들이 고른 금액의 예금을 많이 받는 경우가 아니라면, 그것은 특히 은행의 경우 매우 이상한 반올림 방식으로 보입니다.240만 파운드를 입금해 주세요. 하지만 200만 파운드라고 부르겠습니다.

IEEE 표준 754는 1985년으로 거슬러 올라가며 두 가지 반올림 방식을 모두 제공하지만 표준에 의해 권장되는 은행 방식을 사용합니다.이 위키백과 기사에는 언어가 라운딩을 구현하는 방법에 대한 긴 목록이 있습니다(아래 중 하나가 틀리면 수정하십시오). 대부분은 뱅커스를 사용하지 않지만 학교에서 배우는 라운딩:

  • 함수의 C/C++ 반올림().h는 0에서 멀어집니다(은행가 반올림이 아님).
  • 자바 수학.0에서 반올림합니다(결과를 반올림하고 0.5를 더하며 정수에 캐스트). 십진법에는 대안이 있습니다.
  • Perl은 C와 유사한 방법을 사용합니다.
  • Javascript는 Java의 Math와 동일합니다.동그랗게.

MSDN에서:

기본값은 수학입니다.반올림은 중간점 반올림을 사용합니다.짝수에게. 대부분의 사람들은 학교에서 "0에서 0으로 반올림"이 더 일반적으로 가르쳐지기 때문에 "짝수로 반올림"에 익숙하지 않습니다.NET은 "0에서 반올림"하는 경향을 공유하지 않기 때문에 통계적으로 우수하므로 "짝수 반올림"으로 기본 설정됩니다(반올림되는 숫자가 양수인 경우).

http://msdn.microsoft.com/en-us/library/system.math.round.aspx

Silverlight는 Midpoint Rounding 옵션을 지원하지 않으므로 직접 작성해야 합니다.다음과 같은 것:

public double RoundCorrect(double d, int decimals)
{
    double multiplier = Math.Pow(10, decimals);

    if (d < 0)
        multiplier *= -1;

    return Math.Floor((d * multiplier) + 0.5) / multiplier;

}

확장으로 사용하는 방법을 포함한 예제는 게시물: .NET Silverlight Rounding을 참조하십시오.

SQL 서버가 0.5 대 1로 올라가는 반면 C# 애플리케이션은 그렇지 않은 문제가 있었습니다.따라서 두 가지 다른 결과를 볼 수 있습니다.

다음은 int/long을 사용한 구현입니다.이것이 자바의 라운드 방식입니다.

int roundedNumber = (int)Math.Floor(d + 0.5);

이것은 아마도 여러분이 생각할 수 있는 가장 효율적인 방법일 것입니다.

만약 여러분이 그것을 두 배로 유지하고 십진법을 사용하고 싶다면, 그것은 소수 자릿수를 기준으로 10의 지수를 사용하는 것입니다.

public double getRounding(double number, int decimalPoints)
{
    double decimalPowerOfTen = Math.Pow(10, decimalPoints);
    return Math.Floor(number * decimalPowerOfTen + 0.5)/ decimalPowerOfTen;
}

소수점에 음수 소수를 입력할 수 있고 단어도 괜찮습니다.

getRounding(239, -2) = 200

Silverlight는 Midpoint Rounding 옵션을 지원하지 않습니다.MidpointRounding 열거형을 추가하는 Silverlight의 확장 방법은 다음과 같습니다.

public enum MidpointRounding
{
    ToEven,
    AwayFromZero
}

public static class DecimalExtensions
{
    public static decimal Round(this decimal d, MidpointRounding mode)
    {
        return d.Round(0, mode);
    }

    /// <summary>
    /// Rounds using arithmetic (5 rounds up) symmetrical (up is away from zero) rounding
    /// </summary>
    /// <param name="d">A Decimal number to be rounded.</param>
    /// <param name="decimals">The number of significant fractional digits (precision) in the return value.</param>
    /// <returns>The number nearest d with precision equal to decimals. If d is halfway between two numbers, then the nearest whole number away from zero is returned.</returns>
    public static decimal Round(this decimal d, int decimals, MidpointRounding mode)
    {
        if ( mode == MidpointRounding.ToEven )
        {
            return decimal.Round(d, decimals);
        }
        else
        {
            decimal factor = Convert.ToDecimal(Math.Pow(10, decimals));
            int sign = Math.Sign(d);
            return Decimal.Truncate(d * factor + 0.5m * sign) / factor;
        }
    }
}

출처: http://anderly.com/2009/08/08/silverlight-midpoint-rounding-solution/

간단한 방법은 다음과 같습니다.

Math.Ceiling(decimal.Parse(yourNumber + ""));

.NET으로 반올림한 숫자는 당신이 찾고 있는 답을 가지고 있습니다.

기본적으로 다음과 같습니다.

반환 값

자릿수와 정확도가 같은 가장 가까운 값입니다.값이 두 숫자 중 하나가 짝수이고 다른 하나가 홀수인 경우 짝수가 반환됩니다.값의 정밀도가 자릿수보다 작으면 값이 변경되지 않고 반환됩니다.

이 방법의 동작은 IEEE 표준 754, 섹션 4를 따릅니다.이러한 종류의 라운딩은 때때로 가장 가까운 라운딩 또는 뱅커스 라운딩이라고 불립니다.숫자가 0이면 이러한 반올림을 0을 향해 반올림이라고도 합니다.

사용자 정의 반올림 사용

public int Round(double value)
{
    double decimalpoints = Math.Abs(value - Math.Floor(value));
    if (decimalpoints > 0.5)
        return (int)Math.Round(value);
    else
        return (int)Math.Floor(value);
}

제가 해결해야 할 방법은 다음과 같습니다.

Public Function Round(number As Double, dec As Integer) As Double
    Dim decimalPowerOfTen = Math.Pow(10, dec)
    If CInt(number * decimalPowerOfTen) = Math.Round(number * decimalPowerOfTen, 2) Then
        Return Math.Round(number, 2, MidpointRounding.AwayFromZero)
    Else
        Return CInt(number * decimalPowerOfTen + 0.5) / 100
    End If
End Function

1.905는 2자리 숫자이고 1.91은 1.91입니다.Math.Round(1.905,2,MidpointRounding.AwayFromZero)1을 줍니다.90을 줍니다!Math.Round 메서드는 프로그래머들이 직면할 수 있는 대부분의 기본적인 문제들에서 절대적으로 일관성이 없고 사용할 수 없습니다.나는 확인해야 합니다.(int) 1.905 * decimalPowerOfTen = Math.Round(number * decimalPowerOfTen, 2)왜냐하면 저는 둥글게 해야 할 것을 둥글게 만들고 싶지 않기 때문입니다.

이것은 매우 추하지만 항상 정확한 산술 반올림을 생성합니다.

public double ArithRound(double number,int places){

  string numberFormat = "###.";

  numberFormat = numberFormat.PadRight(numberFormat.Length + places, '#');

  return double.Parse(number.ToString(numberFormat));

}

언급URL : https://stackoverflow.com/questions/977796/why-does-math-round2-5-return-2-instead-of-3

반응형