연산자 소개 및 단항, 산술 연산자 사용하기
이번 강의는 데이터를 가공하는데 사용되는 풍부한 연산자에 대해서 다룹니다.
> // 연산자(Operator): 데이터와 변수를 가지고 덧셈(+), 뺄셈(-)과 같은 연산 작업을 수행
1. 연산자
데이터를 가지고 연산 작업을 수행하고자 할 때 **연산자(Operator)**를 사용합니다. 연산자는 기능에 따라 대입, 산술, 관계, 논리, 증감, 조건, 비트, 시프트 연산자 등으로 나뉘며 이용 형태에 따라 한 개의 항을 가지고 연산을 하는 단항(Unary) 연산자와 두 개의 항을 연산하는 이항(Binary) 연산자와 세 개의 항을 연산하는 삼항(Ternary) 연산자로 나뉩니다.
그림: 연산자
연산자와 피연산자
이러한 연산에는 연산자와 피연산자가 있습니다. 예를 들어 다음과 같은 C# 코드가 있다고 가정합시다.
> int num = 1000;
> int number = num + 1234;
> number
2234
+
기호를 연산자(operator)라고 하고 num
과 1234
는 피연산자(operand)라고 합니다.
식과 문
하나의 값 또는 연산을 진행하는 구문의 계산식을 식(Expression) 또는 표현식이라고 합니다. 예를 들어 3 + 5
와 같은 코드는 식입니다. 표현식을 사용하여 하나의 명령을 진행하는 구문을 문(Statement) 또는 문장이라고 합니다. 예들 들어 x = 3 + 5;
와 같은 코드가 바로 문입니다.
식과 문을 사용하는 예를 실행해 봅시다.
코드: OperatorDescription.cs
> //[?] 연산자(Operator): 덧셈, 뺄셈과 같은 연산을 진행하는 키워드
> //[?] 식(Expression)
> 3 + 5
8
> 3 - 5
-2
>
> //[?] 문(Statement)
> Console.WriteLine(3 * 5); // 15
15
> Console.WriteLine(3 / 5); // 0
0
3 + 5
형태를 식이라고 하고 일반적으로 세미콜론으로 구분되는 하나의 문장을 문이라고 합니다.
단항 연산자(Unary Operator)
단항 연산자는 하나의 연산자로 식을 처리합니다. 단항 연산자의 가장 기본인 +
연산자와 -
연산자를 먼저 살펴보겠습니다.
표: 단항 연산자
연산자 | 설명 |
---|---|
+ 연산자 | 특정 정수형 변수의 값을 그대로 출력합니다. 사실, 단항 연산자인 + 연산자는 특정 기능이 없습니다. |
- 연산자 | 특정 정수형 변수의 값을 음수로 변경하여 출력합니다. 만약, 음수의 값이 들어 있다면 양수로 변환해서 반환해 줍니다. |
단항 연산자 사용하기
이번에는 단항 연산자를 사용해보겠습니다. 다음 내용을 C# Interactive 또는 프로젝트를 만들고 입력한 뒤 실행해보세요.
코드: UnaryOperator.cs
> //[?] 단항 연산자(Unary Operator): +, -
> int value = 0;
>
> value = 8; // value에 8 대입
> value = +value; // value의 값에 + 기호로 붙여 있는 그대로 표현
> value
8
>
> value = -8; // value에 -8 대입
> value = +value; // value의 값에 + 기호를 붙여 있는 그대로 표현
> value
-8
>
> value = 8; // value에 8 대입
> value = -value; // value의 값에 - 기호를 붙여 부호를 반대로 변경
> value
-8
>
> value = -8; // value에 -8 대입
> value = -value; // value의 값에 - 기호를 붙여 부호를 반대로 변경
> value
8
+
연산자는 변수의 값을 그대로 반환해 줍니다. 이와 달리 –
연산자는 변수의 값의 부호를 반대로 변경해 줍니다.
형식 변환 연산자: ()
를 사용하여 데이터 형식 변환
()
기호를 사용하여 특정 값을 원하는 데이터 형식으로 변환할 수 있습니다. 이를 형식 변환(cast)이라고 합니다. (int)3.14
를 사용하면 실수 리터럴인 3.14
를 정수형으로 변환해서 3
을 반환해 줍니다.
변환 연산자를 사용해 보겠습니다.
코드: CastingOperator.cs
> int number = (int)3.14; // 3.14를 정수(int)로 변환
> number
3
실수 데이터 형식인 3.14
를 (int)
를 붙여 정수 데이터 형식 변수에 담았습니다.
변환 연산자는 (long)
, (double)
형태로도 사용됩니다.
> long number = (long)3.141592;
> number
3
> double number = (double)3.141592;
> number
3.141592
산술 연산자(Arithmetic Operator)
이번에는 사칙역산을 할 수 있는 방법을 알아보겠습니다. C#에서는 사칙연산을 위해서 산술 연산자(Arithmetic Operator)를 제공합니다. 산술 연산자는 덧셈(Add), 뺄셈(Subtract), 곱셈(Multiply), 나눗셈(Divide), 나머지(Remainder, Modulus)의 수학적 연산을 하는데 사용됩니다.
산술 연산자는 정수 형식과 실수 형식의 산술 연산에 사용됩니다.
동영상 강의: 산술 연산자(Arithmetic Operator) 의사 코드로 소개
산술 연산자는 다음과 같이 5가지 종류가 있습니다.
+ (덧셈), - (뺄셈), * (곱셈), / (나눗셈), % (나머지)
다음은 산술 연산자 사용 예입니다.
연산자 | 의미 | 설명 |
---|---|---|
A + B |
덧셈 | A와 B를 더한 값을 반환합니다. |
A - B |
뺄셈 | A에서 B를 뺀 값을 반환합니다. |
A * B |
곱셈 | A와 B를 곱한 값을 반환합니다. |
A / B |
나눗셈 | A를 B로 나눈 값을 반환합니다. |
A % B |
나머지 | A를 B로 나눈 후, 몫이 아닌 나머지 값을 반환합니다. |
기타, +
연산자는 문자열과 문자열을 묶는 기능도 합니다.
사칙 연산과 산술 연산자 그리고 실수 데이터 형식의 오차 소개
C#은 간단한 산술 연산을 수행하는 사칙 연산자(+, -, *, /, %)를 지원합니다.
> // 사칙 연산
> 3 + 5
8
> 3 - 5
-2
> 3 * 5
15
> 10 / 5
2
> 3 % 5 // 나머지
3
이들 연산자는 덧셈, 뺄셈, 곱셈, 나눗셈, 그리고 나머지 연산을 수행합니다. 이들은 모두 정수 또는 실수 데이터에 사용할 수 있습니다.
그러나, 실수를 사용할 때 주의해야 할 점이 있습니다. 실수는 컴퓨터에서 완벽하게 표현할 수 없는 경우가 있기 때문에, 계산 결과에 미세한 오차가 생길 수 있습니다. 아래의 예를 보면 3.141592 - 3.0
의 결과가 정확히 0.141592
가 아닌 0.14159200000000016
으로 출력되는 것을 볼 수 있습니다.
> 3.141592 - 3.0
0.14159200000000016
이러한 문제를 해결하기 위해 C#은 정밀도가 더 높은 decimal
데이터 형식을 제공합니다. decimal
을 사용하면 위의 연산에서 발생하는 미세한 오차를 피할 수 있습니다.
> decimal PI = 3.14159M;
> PI - 3.0M
0.14159
decimal
데이터 형식은 주로 금융 계산과 같이 높은 정밀도가 필요한 경우에 사용됩니다. 하지만, decimal
은 double
이나 float
에 비해 메모리를 더 많이 사용하고, 연산 속도가 느릴 수 있으므로, 필요한 경우에만 사용하는 것이 좋습니다.
산술 연산자 사용하기
다음 샘플 코드는 +
연산자를 사용하여 더한 값을 출력한 내용입니다.
코드: PlusOperator.cs
> int i = 10;
> int j = 20;
> int k = i + j;
> k
30
덧셈 연산자: +
먼저, 덧셈 연산자를 사용해보겠습니다.
코드: OperatorAdd.cs
//[?] 덧셈(+) 연산자
using System;
class OperatorAdd
{
static void Main()
{
int i = 10;
int j = 20;
int k = i + j; // k = 10 + 20
Console.WriteLine(k); // 30
}
}
30
k
변수에는 i
와 j
변수에 있는 값을 더한 후 그 결괏값을 저장합니다. 10
과 20
의 합을 더한 결괏값인 30
이 k
에 저장되어 출력됩니다.
뺄셈 연산자: -
이번에는 뺄셈 연산자를 사용해보겠습니다. 정수와 마찬가지로 산술 연산자는 실수도 동일하게 산술연산을 처리합니다. 실수 데이터를 저장할 수 있는 decimal
형식은 3.14M
형태처럼 M
을 접미사로 붙여서 초기화 합니다.
코드: OperatorSubtract.cs
> //[?] 뺄셈(-) 연산자
> decimal i = 3.14M;
> decimal j = 3.14M;
> decimal k = i - j; // k = 3.14 + 3.14
> k
0.00
뺄셈(-
) 연산자를 사용하면 정수 또는 실수 데이터 형식의 변수를 빼는 기능을 합니다. k = i - j;
코드에 의해서 i
값에서 j
값을 뺀 결괏값이 k
에 담깁니다.
곱셈 연산자: *
이번에는 곱셈 연산자를 사용해보겠습니다.
코드: OperatorMultiply.cs
> //[?] 곱셈(*) 연산자
> long i = 100;
> long j = 200;
> long k = i * j; // k = 100 * 200
> k
20000
곱셈(*
) 연산자는 키보드의 *
기호를 사용합니다. k = i * j;
코드에 의해서 i
값과 j
값을 곱한 결괏값이 k
에 담깁니다.
*
기호는 애스터리스크라고 합니다. 다음 문서는 시간나면 한 번 읽어보고 넘어가세요.
나눗셈 연산자: /
이번에는 나눗셈 연산자를 사용해보겠습니다.
코드: OperatorDivide.cs
> //[?] 나눗셈(/) 연산자
> double i = 1.5;
> double j = 0.5;
> double k = i / j; // k = 1.5 / 0.5
> k
3
> 3 / 0
(1,1): error CS0020: Division by constant zero
수학에서 사용하는 나눗셈 기호는 키보드에 없기 때문에 슬래시(/
) 기호를 사용하여 나눗셈 기능을 구현합니다. k = i / j;
코드에 의해서 i
값에 j
값을 나눈 결괏값이 k
에 담깁니다.
참고로, 나눗셈 연산은 0
으로 나누면 에러가 발생합니다.
나머지 연산자: %
C#에서 퍼센트(%
) 기호를 사용하는 나머지 연산자는 나눗셈 연산의 결과 중 몫이 아닌 나머지를 구해주는 연산자입니다.
코드: Remainder.cs
> 5 % 3
2
이번에는 나머지 연산자를 사용해보겠습니다.
코드: OperatorRemainder.cs
//[?] 나머지(%) 연산자
using System;
class OperatorRemainder
{
static void Main()
{
int i = 5;
int j = 3;
int k = i % j; // k = 5 % 3
Console.WriteLine(k); // 2
}
}
2
k = i % j;
코드에 의해서 i
값에 j
값을 나눈 후 나머지 값이 k
에 담깁니다.
나머지 연산자의 결괏값이 0
인 경우는 나눈 수로 정확히 나누어 떨어진다는 것을 의미하여 짝수 또는 홀수 등 특정 수의 배수를 판별할 때 유용하게 사용할 수 있습니다. 예를 들어 모든 수를 2
로 나누었을 때 나머지가 0
이면 짝수를 의미하고 나머지가 1
이면 홀수를 의미하는데 이러한 식을 구현할 때 나머지 연산자(%
)가 사용됩니다.
참고로, 다음과 같은 식으로 나머지 연산자없이 나머지 값을 구할 수도 있습니다.
r = x – (x / y) * y
나머지 연산자에 대한 내용을 한번 더 살펴보겠습니다.
코드: PercentOperator.cs
> int f = 10;
. int s = 5;
. int r = f % s; // r 변수에는 (f / s) 결과의 나머지 값이 저장
. Console.WriteLine("{0} % {1} = {2}", f, s, r);
10 % 5 = 0
f % s
식에 의해서 10 % 5
가 되는데 몫은 2
이고 나머지는 0
이 됩니다. 이 때 나머지 값인 0
이 r
변수에 담깁니다.
산술 연산자 전체 사용하기
간단하게 2개의 변수를 이용해서 산술 연산을 하는 프로그램을 작성해보겠습니다. 특히 나머지 값을 구해주는 %
연산자를 주의 깊게 살펴보겠습니다.
코드: OperatorArithmetic.cs
// +, -, *, /, %
using System;
class OperatorArithmetic
{
static void Main()
{
int a = 5;
int b = 3;
Console.WriteLine(a + b); // 덧셈: 8
Console.WriteLine(a - b); // 뺄셈: 2
Console.WriteLine(a * b); // 곱셈: 15
Console.WriteLine(a / b); // 몫: 1
Console.WriteLine(
"{0} % {1} = {2}", a, b, (a % b)); // 나머지: 2
}
}
8
2
15
1
5 % 3 = 2
일상적인 생활과는 달리 나머지를 구하는 %
연산자는 프로그램 코드에서는 자주 나타나는 연산자입니다.
문자열 연결 연산자(Addition Operator)
산술 연산자 중의 하나인 +
연산자는 경우에 따라 산술 연산 또는 문자열 연결 연산을 수행합니다.
`+` 연산자: 두 항이 숫자일 경우 산술(`+`) 연산 기능, 문자열일 경우 **문자열 연결** 기능
문자열 연결 연산자의 사용 예는 다음과 같습니다.
코드 예 | 출력 결과 | 참고 |
---|---|---|
"Hello" + "World" | "HelloWorld" | |
"Hi" + " " + "everyone" | "Hi everyone" | |
"123" + "456" | "123456" | 혼동하는 경우가 발생 |
"123" + 456 | "123456" | |
123 + 456 | 579 | 산술 연산(+) |
덧셈 연산자(Addition Operator)의 추가적인 특징
덧셈 연산자인 +
연산자는 숫자 값의 데이터는 산술 연산을 하고 문자열이 포함된 연산에서는 문자열을 더하는 기능을 합니다
.
이번에는 덧셈 연산자의 여러가지 사용 방법을 알아보겠습니다.
코드: AdditionOperator.cs
//[?] 덧셈(Addtion) 연산자의 추가적인 특징
using System;
class AdditionOperator
{
static void Main()
{
Console.WriteLine("Hello" + "World"); // 문자열 덧셈
Console.WriteLine("Hi" + " " + "everyone");
Console.WriteLine("123" + "456"); // "123456" => 숫자형 문자열은 문자열로 취급
Console.WriteLine("123" + 456); // "123456" => 문자열과 숫자형은 문자열로 취급
Console.WriteLine(123 + "456"); // "123456"
Console.WriteLine(123 + 456); // 산술연산 => 숫자들끼리는 산술 연산
Console.WriteLine("123" + true); // 123True => bool 형식과의 덧셈은 문자열 취급
//Console.WriteLine("123" - 456); // 에러: 문자열에서 정수를 뺄 수 없음
}
}
HelloWorld
Hi everyone
123456
123456
123456
579
123True
+
연산자는 문자열과 문자열은 묶어줍니다. 또한 숫자 모양의 문자열과 숫자끼리는 문자열로 묶어줍니다.
참고로, 다음과 같은 뺄셈 연산은 에러가 발생합니다.
> "123" - 456
(1,1): error CS0019: Operator '-' cannot be applied to operands of type 'string' and 'int'
> "123" - 456
(1,1): error CS0019: '-' 연산자는 'string' 및 'int' 형식의 피연산자에 적용할 수 없습니다.
참고: 숫자 형식을 문자열로 변환하기
숫자 데이터 형식은 암시적으로 문자열과 덧셈 연산이 가능합니다. 다만, 암시적보다는 명시적으로 변환 후 덧셈 연산을 하는 것을 권장합니다. 다음 코드를 살펴보세요. ToString()
메서드와 Convert.ToString()
메서드를 사용하여 숫자 형식을 문자열 형식으로 변경하는 내용입니다.
코드: NumberToString.cs
> int days = 28;
> //[1] 암시적(Implicit)으로 숫자 형식을 문자열로 변환하기
> "2월달은 " + days + "일입니다."
"2월달은 28일입니다."
> //[2] 명시적(Explicit)으로 숫자 형식을 문자열로 변환하기: 2가지 방법
> "2월달은 " + days.ToString() + "일입니다."
"2월달은 28일입니다."
> "2월달은 " + Convert.ToString(days) + "일입니다."
"2월달은 28일입니다."
C# 프로그래밍에서 정수 나눗셈의 정밀도 문제 이해하기
이 글에서는 C#에서 정수 나눗셈을 실수형 변수에 저장할 때 발생할 수 있는 정밀도 손실 문제를 예시 코드를 통해 설명하고, 이를 해결하기 위한 방안을 제시하겠습니다.
초기 코드 분석
다음은 C# 언어로 작성된 초기 코드 예시입니다:
코드: C:\DotNet\DotNet\DotNet\09_Operator\PrecisionDemo\PrecisionDemo.cs
using System;
class PrecisionDemo
{
static void Main()
{
int dividend = 3, divisor = 4;
double quotient;
quotient = dividend / divisor;
Console.WriteLine("Division result: {0}", quotient);
}
}
예상 출력 및 문제점
이 코드에서는 두 정수 dividend
(피제수)와 divisor
(제수)를 나누고, 그 결과를 실수형 변수 quotient
(몫)에 저장합니다. 그러나 dividend / divisor
는 두 변수 모두 정수형이기 때문에 정수 나눗셈이 수행됩니다. 3 / 4
는 정수 결과로 0
을 반환하므로, quotient
에는 0.0
이 저장되며, 출력 결과는 "Division result: 0.0"입니다. 이는 소수점 이하의 정밀한 결과를 얻을 수 없는 문제가 있습니다.
개선된 코드와 해결 방안
문제를 해결하기 위해서 나눗셈 연산 중 하나의 피연산자를 실수형(double
)으로 캐스팅하여 실수 나눗셈으로 변경하였습니다. 개선된 코드는 다음과 같습니다:
코드: C:\DotNet\DotNet\DotNet\09_Operator\PrecisionDemo\PrecisionDemo.cs
using System;
class PrecisionDemo
{
static void Main()
{
int dividend = 3, divisor = 4;
double quotient;
quotient = (double)dividend / divisor; // 개선된 부분
Console.WriteLine("Division result: {0}", quotient);
}
}
Division result: 0.75
이 변경으로 quotient
는 0.75
로 계산되며, 출력 결과는 "Division result: 0.75"입니다. 이제 코드는 정수 나눗셈이 아닌 실수 나눗셈을 수행하여 소수점 이하의 값을 정확히 반영할 수 있습니다.
장 요약
이번 강의는 단항 연산자인 +
, -
그리고 산술 연산자인 +
, -
, *
, /
, %
연산자에 대해 살펴보았습니다. 계속해서 추가적인 연산자들을 학습해나가겠습니다.
1.1 퀴즈
(1) 값이나 변수를 더하는 방법으로 올바르지 않은 것을 고르세요.
int number1 = 10;
int number2 = 20;
int number3;
a. number3 = number1 + number2;
b. number3 = 10 + 20;
c. number3 = number1 + 10;
d. number3 = +number2;
정답: d
+
연산자가 단항 연산자로 사용될 경우, 변수의 부호를 그대로 유지하는 역할을 합니다.
따라서number3 = +number2;
는 덧셈 연산이 아닌, 단순한 부호 유지 표현입니다.
(2) 변수 number1
의 값을 10 감소시키는 올바른 방법을 고르세요.
a. number1 = number1 - 10;
b. number1 = number1 + 10;
c. number1 = +number1;
d. number1 = 10 - number1;
정답: a
number1 = number1 - 10;
은number1
의 기존 값에서10
을 빼어 다시 저장하는 방식입니다.
- b:
+10
을 더하는 연산이므로 감소가 아님- c:
+number1
은 부호 유지로, 값 변화 없음- d:
10 - number1
은 원래 값이 아닌10
에서number1
을 뺀 값이 저장됨
1.2 연습문제: 나머지 연산자를 사용하여 나머지 값 구하기
다음 소스 코드를 완성하여 r
변수에 x
를 y
로 나눈 나머지 값을 저장하세요.
코드
using System;
class OperatorRemainderPractice
{
static void Main()
{
int x = 8;
int y = 5;
int s = x / y; // 몫
int r = x % y; // 나머지
Console.WriteLine($"{x} 나누기 {y} -> 몫: {s}, 나머지: {r}");
}
}
실행 결과
8 나누기 5 -> 몫: 1, 나머지: 3
정답
x % y
해설
C#에서 나누기 연산 후 나머지를 구할 때는 %
(나머지 연산자) 연산자를 사용합니다.
/
연산자는 몫을 반환 (8 / 5 = 1
)%
연산자는 나머지를 반환 (8 % 5 = 3
)