산술 연산자(C# 참조)

다음 연산자는 숫자 형식 피연산자를 포함한 산술 작업을 수행합니다.

해당 연산자는 모든 정수부동 소수점 숫자 형식을 지원합니다.

정수 형식의 경우 이러한 연산자(++-- 연산자 제외)는 int, uint, longulong 형식에 대해 정의됩니다. 피연산자가 다른 정수 형식(sbyte, byte, short, ushort 또는 char)인 경우, 해당 값은 연산의 결과 형식이기도 한 int 형식으로 변환됩니다. 피연산자가 정수 형식 또는 부동 소수점 형식인 경우 해당 형식이 있으면 값은 가장 근사한 포함하는 형식으로 변환됩니다. 자세한 내용은 C# 언어 사양숫자 승격 섹션을 참조하세요. ++-- 연산자는 모든 정수 형식 및 부동 소수점 숫자 형식과 char 형식에 대해 정의됩니다. 복합 할당 식의 결과 형식은 왼쪽 피연산자의 형식입니다.

증가 연산자 ++

단항 증가 연산자(++)는 피연산자를 1씩 증가합니다. 피연산자는 변수, 속성 액세스 또는 인덱서 액세스여야 합니다.

증가 연산자는 후위 증가 연산자 x++ 및 전위 증가 연산자 ++x라는 두 가지 양식으로 지원됩니다.

후위 증가 연산자

의 결과는 x++ 다음 예제와 같이 작업 x 값입니다.

int i = 3;
Console.WriteLine(i);   // output: 3
Console.WriteLine(i++); // output: 3
Console.WriteLine(i);   // output: 4

후위 증가 연산자

의 결과는 ++x 다음 예제와 같이 작업 x 값입니다.

double a = 1.5;
Console.WriteLine(a);   // output: 1.5
Console.WriteLine(++a); // output: 2.5
Console.WriteLine(a);   // output: 2.5

감소 연산자 --

단항 감소 연산자(--)는 피연산자를 1씩 감소합니다. 피연산자는 변수, 속성 액세스 또는 인덱서 액세스여야 합니다.

감소 연산자는 후위 감소 연산자 x-- 및 전위 감소 연산자 --x라는 두 가지 양식으로 지원됩니다.

후위 감소 연산자

의 결과는 x-- 다음 예제와 같이 작업 x 값입니다.

int i = 3;
Console.WriteLine(i);   // output: 3
Console.WriteLine(i--); // output: 3
Console.WriteLine(i);   // output: 2

후위 감소 연산자

의 결과는 --x 다음 예제와 같이 작업 x 값입니다.

double a = 1.5;
Console.WriteLine(a);   // output: 1.5
Console.WriteLine(--a); // output: 0.5
Console.WriteLine(a);   // output: 0.5

단항 더하기 및 빼기 연산자

단항 + 연산자는 피연산자의 값을 반환합니다. 단항 - 연산자는 피연산자의 숫자 부정을 계산합니다.

Console.WriteLine(+4);     // output: 4

Console.WriteLine(-4);     // output: -4
Console.WriteLine(-(-4));  // output: 4

uint a = 5;
var b = -a;
Console.WriteLine(b);            // output: -5
Console.WriteLine(b.GetType());  // output: System.Int64

Console.WriteLine(-double.NaN);  // output: NaN

단항 - 연산자는 ulong 형식을 지원하지 않습니다.

곱하기 연산자 *

곱하기 연산자 *는 피연산자의 곱을 계산합니다.

Console.WriteLine(5 * 2);         // output: 10
Console.WriteLine(0.5 * 2.5);     // output: 1.25
Console.WriteLine(0.1m * 23.4m);  // output: 2.34

단항 * 연산자는 포인터 간접 참조 연산자입니다.

나누기 연산자 /

나누기 연산자 /는 오른쪽 피연산자로 왼쪽 피연산자를 나눕니다.

정수 나누기

정수 형식의 피연산자의 경우 / 연산자의 결과는 정수 형식이고 두 피연산자의 몫과 동일한 값은 0으로 반올림됩니다.

Console.WriteLine(13 / 5);    // output: 2
Console.WriteLine(-13 / 5);   // output: -2
Console.WriteLine(13 / -5);   // output: -2
Console.WriteLine(-13 / -5);  // output: 2

두 피연산자의 몫을 부동 소수점 숫자로 가져오려면 float, double 또는 decimal 형식을 사용하세요.

Console.WriteLine(13 / 5.0);       // output: 2.6

int a = 13;
int b = 5;
Console.WriteLine((double)a / b);  // output: 2.6

부동 소수점 나누기

float, doubledecimal 형식의 경우 / 연산자의 결과는 두 피연산자의 몫입니다.

Console.WriteLine(16.8f / 4.1f);   // output: 4.097561
Console.WriteLine(16.8d / 4.1d);   // output: 4.09756097560976
Console.WriteLine(16.8m / 4.1m);   // output: 4.0975609756097560975609756098

피연산자 중 하나가 decimal이면 float 또는 double 모두 decimal로 암시적으로 변환할 수 없기 때문에 나머지 피연산자는 float 또는 double일 수 없습니다. float 또는 double 피연산자를 decimal 형식으로 암시적으로 변환해야 합니다. 숫자 형식 간의 변환에 대한 자세한 내용은 기본 제공 숫자 변환을 참조하세요.

나머지 연산자 %

나머지 연산자 %는 왼쪽 피연산자를 오른쪽 피연산자로 나눈 후 나머지를 계산합니다.

정수 나머지

정수 형식의 피연산자의 경우 a % b의 결과가 a - (a / b) * b에서 생성된 값입니다. 0이 아닌 나머지의 기호는 다음 예제와 같이 왼쪽 피연산자의 기호와 동일합니다.

Console.WriteLine(5 % 4);   // output: 1
Console.WriteLine(5 % -4);  // output: 1
Console.WriteLine(-5 % 4);  // output: -1
Console.WriteLine(-5 % -4); // output: -1

Math.DivRem 메서드를 사용하여 정수 나누기 및 나머지 결과를 모두 컴퓨팅합니다.

부동 소수점 나머지

floatdouble 피연산자의 경우 유한 xy에 대한 x % y의 결과는 다음과 같은 z 값입니다.

  • 0이 아닌 경우 z의 부호는 x의 부호와 동일합니다.
  • z의 절대 값은 |x| - n * |y|에서 생성된 값입니다. 여기서 n|x| / |y|보다 작거나 같은 가능한 최대 정수이고 |x||y|는 각각 xy의 절대 값입니다.

참고

나머지 계산 방법은 정수 피연산자에 사용되는 것과 유사하지만 IEEE 754 사양과는 다릅니다. IEEE 754 사양을 준수하는 나머지 작업이 필요한 경우 Math.IEEERemainder 메서드를 사용합니다.

무한 피연산자가 있는 % 연산자의 동작에 대한 자세한 내용은 C# 언어 사양나머지 연산자 섹션을 참조하세요.

decimal 피연산자의 경우 나머지 연산자 %System.Decimal 형식의 나머지 연산자와 동일합니다.

다음 예제에서는 부동 소수점 피연산자를 포함한 나머지 연산자의 동작을 보여줍니다.

Console.WriteLine(-5.2f % 2.0f); // output: -1.2
Console.WriteLine(5.9 % 3.1);    // output: 2.8
Console.WriteLine(5.9m % 3.1m);  // output: 2.8

더하기 연산자 +

더하기 연산자 +는 피연산자의 합계를 계산합니다.

Console.WriteLine(5 + 4);       // output: 9
Console.WriteLine(5 + 4.3);     // output: 9.3
Console.WriteLine(5.1m + 4.2m); // output: 9.3

문자열 연결 및 대리자 조합의 경우 + 연산자를 사용할 수도 있습니다. 자세한 내용은 참조는 ++=연산자 문서를 참조하세요.

빼기 연산자 -

빼기 연산자 -는 왼쪽 피연산자에서 오른쪽 피연산자를 뺍니다.

Console.WriteLine(47 - 3);      // output: 44
Console.WriteLine(5 - 4.3);     // output: 0.7
Console.WriteLine(7.5m - 2.3m); // output: 5.2

대리자 제거를 위해 - 연산자를 사용할 수도 있습니다. 자세한 내용은 참조는 --=연산자 문서를 참조하세요.

복합 할당

이진 연산자(op)의 경우 양식의 복합 할당 식

x op= y

위의 식은 아래의 식과 동일합니다.

x = x op y

단, x가 한 번만 계산됩니다.

다음 예제에서는 산술 연산자를 사용하는 복합 할당의 사용법을 보여줍니다.

int a = 5;
a += 9;
Console.WriteLine(a);  // output: 14

a -= 4;
Console.WriteLine(a);  // output: 10

a *= 2;
Console.WriteLine(a);  // output: 20

a /= 4;
Console.WriteLine(a);  // output: 5

a %= 3;
Console.WriteLine(a);  // output: 2

숫자 승격으로 인해 op 연산의 결과가 암시적으로 xT 형식으로 변환되지 못할 수 있습니다. 이 경우 op가 미리 정의된 연산자이고 연산의 결과가 명시적으로 xT 형식으로 변환 가능하다면 x op= y 양식의 복합 할당 식이 x = (T)(x op y)에 해당합니다. 단 x는 한 번만 평가됩니다. 다음 예제에서는 해당 동작을 보여줍니다.

byte a = 200;
byte b = 100;

var c = a + b;
Console.WriteLine(c.GetType());  // output: System.Int32
Console.WriteLine(c);  // output: 300

a += b;
Console.WriteLine(a);  // output: 44

각각 +=-= 연산자를 사용하여 이벤트에서 구독하거나 구독을 취소할 수도 있습니다. 자세한 내용은 이벤트를 구독 및 구독 취소하는 방법을 참조하세요.

연산자 우선 순위 및 결합성

다음 목록에서는 산술 연산자를 가장 높은 우선 순위부터 가장 낮은 것으로 정렬합니다.

  • 후위 증가 x++ 및 감소 x-- 연산자
  • 전위 증가 ++x 및 감소 --x 및 단항 +- 연산자
  • 곱하기 *, /% 연산자
  • 가감 +- 연산자

이진 산술 연산자는 왼쪽 결합형입니다. 즉, 우선 순위 수준이 같은 연산자는 왼쪽에서 오른쪽으로 계산됩니다.

괄호(())를 사용하여 연산자 우선 순위와 연결에 따라 주어진 계산 순서를 변경할 수 있습니다.

Console.WriteLine(2 + 2 * 2);   // output: 6
Console.WriteLine((2 + 2) * 2); // output: 8

Console.WriteLine(9 / 5 / 2);   // output: 0
Console.WriteLine(9 / (5 / 2)); // output: 4

우선 순위 수준에 따라 정렬된 전체 연산자 목록은 C# 연산자 문서의 연산자 우선 순위 섹션을 참조하세요.

산술 오버플로 및 0으로 나누기

산술 연산의 결과가 관련된 숫자 형식의 가능한 유한 값 범위를 벗어나는 경우 산술 연산자의 동작은 해당하는 피연산자의 형식에 따라 달라집니다.

정수 산술 오버플로

정수를 0으로 나누면 항상 DivideByZeroException이 throw됩니다.

정수 산술 오버플로가 발생하면 검사하거나 선택 취소할 수 있는 오버플로 검사 컨텍스트가 결과 동작을 제어합니다.

  • checked 컨텍스트인 경우 상수 식에서 오버플로가 일어나면 컴파일 시간 오류가 발생합니다. 그렇지 않으면, 런타임 시 작업을 수행하는 경우 OverflowException이 throw됩니다.
  • unchecked 컨텍스트에서는 대상 형식에 맞지 않는 상위 비트를 버려서 해당 결과가 잘려집니다.

확인 및 선택되지 않은 문과 함께 및 unchecked 연산자를 사용하여 checked 식이 평가되는 오버플로 검사 컨텍스트를 제어할 수 있습니다.

int a = int.MaxValue;
int b = 3;

Console.WriteLine(unchecked(a + b));  // output: -2147483646
try
{
    int d = checked(a + b);
}
catch(OverflowException)
{
    Console.WriteLine($"Overflow occurred when adding {a} to {b}.");
}

기본적으로 산술 연산은 unchecked 컨텍스트에서 발생합니다.

부동 소수점 산술 오버플로

floatdouble 형식을 포함한 산술 연산은 예외를 throw하지 않습니다. 이러한 형식의 산술 연산 결과는 무한대를 나타내거나 숫자가 아닌 특수 값 중 하나일 수 있습니다.

double a = 1.0 / 0.0;
Console.WriteLine(a);                    // output: Infinity
Console.WriteLine(double.IsInfinity(a)); // output: True

Console.WriteLine(double.MaxValue + double.MaxValue); // output: Infinity

double b = 0.0 / 0.0;
Console.WriteLine(b);                // output: NaN
Console.WriteLine(double.IsNaN(b));  // output: True

형식의 decimal 피연산자의 경우 산술 오버플로는 항상 을 OverflowExceptionthrow합니다. 0으로 나누면 항상 가 DivideByZeroExceptionthrow됩니다.

반올림 오류

실수 및 부동 소수점 산술의 부동 소수점 표현을 일반적으로 제한함으로 인해 부동 소수점 형식을 사용하는 계산에서 반올림 오류가 발생할 수 있습니다. 즉, 생성된 식의 결과는 예상되는 수학적 결과와 다를 수 있습니다. 다음 예제에서는 이러한 몇몇 사례에 대해 설명합니다.

Console.WriteLine(.41f % .2f); // output: 0.00999999

double a = 0.1;
double b = 3 * a;
Console.WriteLine(b == 0.3);   // output: False
Console.WriteLine(b - 0.3);    // output: 5.55111512312578E-17

decimal c = 1 / 3.0m;
decimal d = 3 * c;
Console.WriteLine(d == 1.0m);  // output: False
Console.WriteLine(d);          // output: 0.9999999999999999999999999999

자세한 내용은 System.Double, System.Single 또는 System.Decimal 참조 페이지에서 설명을 참조하세요.

연산자 오버로드 가능성

사용자 정의 형식은 단항(++, --, +-) 및 이진(*, /, %, +-) 산술 연산자를 오버로드할 수 있습니다. 이항 연산자가 오버로드되면 해당하는 복합 대입 연산자도 암시적으로 오버로드됩니다. 사용자 정의 형식은 복합 할당 연산자를 명시적으로 오버로드할 수 없습니다.

사용자 정의 확인 연산자

C# 11부터 산술 연산자를 오버로드할 때 키워드를 checked 사용하여 해당 연산자의 확인된 버전을 정의할 수 있습니다. 다음 예제에서는 해당 작업을 수행하는 방법을 보여줍니다.

public record struct Point(int X, int Y)
{
    public static Point operator checked +(Point left, Point right)
    {
        checked
        {
            return new Point(left.X + right.X, left.Y + right.Y);
        }
    }
    
    public static Point operator +(Point left, Point right)
    {
        return new Point(left.X + right.X, left.Y + right.Y);
    }
}

확인된 연산자를 정의할 때는 한정자 없이 checked 해당 연산자도 정의해야 합니다. checked 연산자는 확인된 컨텍스트에서 호출됩니다. 한정자가 없는 checked 연산자는 선택되지 않은 컨텍스트에서 호출됩니다. 한정자 없이 checked 연산자만 제공하는 경우 및 unchecked 컨텍스트 모두에서 checked 호출됩니다.

두 버전의 연산자를 모두 정의할 때 연산 결과가 너무 커서 결과 형식을 다음과 같이 나타낼 수 없는 경우에만 해당 동작이 다를 것으로 예상됩니다.

  • 확인된 연산자가 을 OverflowExceptionthrow합니다.
  • 한정자가 없는 checked 연산자는 잘린 결과를 나타내는 인스턴스를 반환합니다.

기본 제공 산술 연산자의 동작 차이에 대한 자세한 내용은 산술 오버플로 및 0으로 나누 기 섹션을 참조하세요.

다음 연산자를 오버로드하는 checked 경우에만 한정자를 사용할 수 있습니다.

참고

확인된 연산자의 본문 내에서 오버플로 검사 컨텍스트는 한정자의 존재 checked 에 의해 영향을 받지 않습니다. 기본 컨텍스트는 CheckForOverflowUnderflow 컴파일러 옵션의 값으로 정의됩니다. 이 섹션의 시작 부분에 있는 예제와 같이 및 unchecked 문을 사용하여 오버플로 검사 컨텍스트를 명시적으로 지정합니다.checked

C# 언어 사양

자세한 내용은 C# 언어 사양의 다음 섹션을 참조하세요.

참고 항목