1. 오늘 학습 키워드
2. 오늘 학습 한 내용을 나만의 언어로 정리하기
연산자: 변수, 값에 대해 계산 또는 조작을 수행하는 기호나 키워드
산술 연산자
+ 더하기
- 빼기
* 곱하기
/ 나누기
% 나머지
++ 증가
-- 감소
나누기/ 나머지 연산 ( / , %)

int x = 17;
int result_1;
int result_2;
result_1=x/5; 이면 3
result_2=x%5; 이면 2
그러나, / 연산보다 *연산이 더 빠르니 *연산을 주로 사용할것.
예를들어
x=10/2 보다
x=10*0.5f 가 더 빠르게 처리된다.
증감연산(++, --) 는 1씩 증감된다.
int x= 10;
x++;
하면 x = 11 값을,
x--;
하면 x= 9 값을 낸다.
변수에 바로 계산
일반적으로 변수는 연산을 한 값을 다시 할당하지 않을 경우는 저장이 안된다. 따라서
int x = 10;
Console.WriteLine(x+10);
Console.WriteLine(x);
라고하면 20, 10 이렇게 출력한다.
int x= 10;
x = x + 10;
Console.WriteLine(x); 할경우
20을 출력한다.
x= x+1; 을 줄여 표현가능하다.
x+=10; 은 x=x+10; 과 같은 뜻이다.
줄이는법은
+=
-=
*=
/=
%=
이렇게 다 가능하다.
※ 그런데, 증감 연산자는 사용하고 다시 할당하지 않더라도 값이 저장된다.
int x = 10;
x++;
Console.WriteLine(x); 하면 10이 아니라 11을 출력한다.
※ 증감 연산은 변수의 앞 뒤에 붙일 수 있다.
x++;
++x; 이런식으로 말이다.
세미콜론(;) 을 기준으로 띄어쓰기를 하고 이를 각 라인이라고 한다.
C#에선 라인을 기준으로 한줄 한줄 작업을 수행한다.
※ 연산자를 뒤에 붙이면 해당 라인이 끝나고 값이 증가
※ 연산자를 앞에 붙이면 해당 라인을 실행할때 증가된 값으로 실행
int x = 10;
Console.WriteLine(x++);
Console.WriteLine(x);
이렇게하면, 10, 11 이렇게 출력한다.
하지만
int y = 10;
Console.WriteLine(++y);
Console.WriteLine(y);
이렇게 하면 11, 11 이렇게 출력한다.
산술연산 - 문자열
문자도 연산이 가능하다, +연산을 활용가능하다.
string hello = "안녕하세요!";
string academy = "스파르타 코딩클럽 입니다!";
string result = hello + academy ;
Console.WriteLine(result);
안녕하세요!스파르타 코딩클럽 입니다!
를 호출한다
변수와 문자열 데이터도 연산 가능하다.
string hello = "안녕!";
string result = hello + "스파르타!"
Console.WriteLine(result);
안녕!스파르타!
를 호출
문자와 숫자도 가능
int year = 2023;
string result = year + "년 입니다.";
Console.WriteLine(result);
2023년 입니다.
를 호출한다.
논리연산 - 같음 연산자
논리연산이란 숫자를 더하고 빼는게 아니라 논리적으로 판단하는 연산자로,
두 값이 같은지, 다른지, 큰지, 작은지를 체크하는 것이다.
두가지 값이 같은지 아닌지 표현 할때
같다는 ==
같지않다는 !=
라고 표현한다.
=는 변수에 데이터를 저장할때 활용되는 연산자이므로 == 인것이다.
int num = 10;
bool isSame = num != 10;
// isSame에 대한 값은 false 가 된다.
비교연산자
<
<= (크거나 같을때)
>
>= (작거나 같을때)
이렇게 표현한다.
논리 연산 정리표다.
|
>
|
a > b
|
a 가 b보다 크면 true
|
|
|
>=
|
a >= b
|
a 가 b보다 크거나 같으면 true
|
|
|
<
|
a < b
|
b 가 a보다 크면 true
|
|
|
<=
|
a <= b
|
b 가 a보다 크거나 같으면 true
|
|
|
==
|
a == b
|
a 와 b 가 같으면 true
|
= 이랑 헷갈리지 마세요!!!!!!
|
|
!=
|
a != b
|
a 와 b 가 다르면 true
|
|
|
&&
|
a && b
|
두가지 조건이 모두 만족하면 true
|
|
|
||
|
a || b
|
둘 중 하나만 만족하면 true
|
추가적으로 자료형 bool 에 대해서 알아보자.
논리 연산의 결과로 얻게되며 제어문에서 핵심적인 기능을 하는 자료형
true
false
즉 참, 거짓의 값을 낸다.
int age = 25;
bool isAdult = age>19;
isAdult 의 값은 true 가 된다.

비트연산자
어려운 연산을 최적화 할때 사용한다.
& : a&b : a와b 비트가 일치하는 것을 계산 : And 연산자
| : a|b : a와 b 비트 중 하나만 일치해도 계산 : Or 연산자
^: a^b : a와 b 비트가 다른것만 계산 : Xor 연산자
<< : a<<b : a의 비트를 왼쪽으로 b 만큼 이동 : 시프트 연산자
>>: a>>b : a의 비트를 오른쪽으로 b만큼 이동 : 시프트 연산자
이렇게 있으며 비트에 대하여 더 자세히 풀어보자면,
컴퓨터는 2진수로 되어있다.
예를 들어
Int 는 4byte 다.
이를 이해가 가도록 표현해보면,

1byte 가 8bit 다.
이중에 8bit 만 때서 얘기해보자.
0000 0000
이 비트를 연산하는 것이 비트 연산이다.
먼저 And 연산자 : & 는
2개를 모두 충족 하는 지 확인하는데,
먼저 10과 3을 2진수로 변환해서 예시를 들어보자.
2진수로 만드는 법은 , 10을 2로 계속 나누면서 몫이 딱 떨어지면, 0 나머지가 1이 나오면 그걸 반영하면서 오른쪽 부터 표기하면 된다.
따라서 이런식으로 표기되는데,
10 0000 1010
3 0000 0011

두 비트 중 값이 1인것만 체크한다.

따라서, 연산결과
2 0000 0010 이 된다.
Or 연산자 : | 는
2개 중 하나가 충족하는지 확인하는 연산자
따라서 , 두 비트 중 하나라도 1인것 모두 체크한다.

그래서 10|3 의 경우 11이 된다.
11 은 0000 1011 이기 때문이다.
Xor 연산자 : ^
는 두 비트가 서로 다른지 확인하는 연산자.
따라서, 두 비트 중 서로 다른것을 모두 체크한다.

따라서
9 0000 1001 이 튀어나온다.
시프트 연산자 : << , >>
비트를 움직이는데 왼쪽, 오른쪽으로 움직인다.
10<<2 를 연산해보면
10 0000 1010 에서 1인 비트를 해당 방향(왼쪽)으로 2만큼 움직이면된다.
따라서,
40 0010 1000 이 된다.
10>>1 을 연산해보면 1인 비트를 오른쪽으로 1만큼 움직이므로,
5 0000 0101 이 된다.
여기서 5>>1 해서 연산을 한 것이 끝을 넘어간다면?
넘어간 데이터는 그대로 사라집니다.
2 0000 0010
★ 다만, 양수와 음수는 다른데,
- 양수(부호비트=0) → 빈 자리에는 0이 채워지고
- 음수(부호비트=1) → 빈 자리에는 1이 채워집니다
8비트 예시를 좀더 들어보자면
양수 5의 경우
0000 0101 인데,
>>7 할경우 오른쪽으로 7칸 이동해서
0000 0000 이되며 결과 0
음수 -5의 경우
1111 1011 인데,
>>7 할경우 오른쪽으로 7칸 이동하면서 1이 채워지므로
1111 1111 로 결과 -1 이된다.
(부호 있는 비트로 읽을때, 가장 왼쪽 비트가 1이면 음수로 인식한다. 따라서 1111 111 은 8비트 '부호 있는' (signed 타입) 정수체계라면 255가 아니라, -128 + 127 해서 -1 이라고 읽는다)
다시, 정리하자면,
And 연산자 : & 의 경우 두 비트가 모두 1일때만 1
OR 연산자 : | 의 경우 두 비트 중 하나 이상 1이면 1
XOR 연산자 : ^ 의 경우 두 비트 가 다를때 1
왼쪽 시프트 : << n 의 경우 ×2ⁿ
오른쪽 시프트 : >>n 의 경우 ÷2ⁿ
NOT : ~ 의 경우 비트 반전을 한다 예를들어 ~1010은 0101 이 된다. 부호 비트 고려한다.
궁금증: 어려운 연산을 최적화 할때 쓴다는데 왜?
하나의 기계어 명령어로 처리가능해서 산술연산(곱셈, 나눗셈등) 보다 매우 빠르다.
즉 어려운연산(복잡한 수학연산) 을 쉬운(비트연산)으로 대체하여 성능을 최적화 한다는 뜻.
대부분 CPU 프로세서가 AND, OR ,SHIFT 같은 비트 연산을 1사이클에 처리한다. 비유하자면 컵에 물 붓기다.
그런데 곱셈이나 나눗셈은 연산을 3~10단계 이상의 사이클을 요구하고, 비유하자면 반죽 만들고 ,굽고 , 식히는 과정이 필요하다.
CPU Cycle 이란 cpu가 한가지 작은 작업을 처리하는 최소 단위 시간이다.
1사이클 : 명령 하나 처리하는 시간이라고 이해하면 좋다.
cpu 내부에는 논리게이트(logic-gat) 라는 전자 스위치가 있고 And 게이트, Or 게이트 같은 회로가 전기 신호(0/1)를 조합해서 결과를 낸다. 비트 연산은 이 논리 게이트 하나만 쓰기 때문에 한 사이클에서 끝나는 것이다.
곱셈이나 나눗셈은 여러 게이트를 연결해 단계별로 계산해야해서 여러 사이클이 필요하다.
그리고
Latency (지연) : 명령을 시작해서 결과가 나올때까지 걸리는 시간(사이클 수)
Pipeline: cpu가 여러명령을 동시에 겹쳐서 처리하는 방식.
Stall : 어떤 명령이 오래걸리면 뒤에 줄 서 있는 명령들이 대기해야 하는 상황.
이라는 용어를 간단히 이해하고 가자면,
비트연산은 latency가 아주 낮아서 파이프라인이 멈추지않고 쭉 돌아간다. stalls를 줄인다.
그래서 실제 최적화 예시를 보자면,
x*8 은 비트 최적화시, x<<3
x/4 은 비트 최적화시, x>>2
x%2 은 x&1
(해당 부분은 이해가 안되서 더 구체화하자면, )
- 짝수일 땐 나머지가 0 → 이진수 끝자리가 0
- 홀수일 땐 나머지가 1 → 이진수 끝자리가 1
1은 이진수로 0000 0001
예를 들어 4 % 2 는 0 이고 5%2 는 1인걸 알 수 있는데.
비트연산으로 바꾸면
4 &1 의 경우,
4는 2진수로 0000 0100 이므로 두 비트중 값이 1인걸 찾아봐서 체크해봤지만 없다, 따라서 0000 0000 인데 이럼 그냥 10진수로 0이다.
5&1의 경우,
5는 2진수로 0000 0101 인데, 두 비트중 값이 1인걸 찾아봐서 체크해보니 2⁰ 부분이 1로 같다, 따라서 0000 0001 이므로 10진수로 1이 된다.
따라서 x % 2와 x & 1은 같은 결과를 내지만, & 연산이 더 빠르다.
또다른 예시로,
abs(x) 그러니까 (absolute value) 라는 함수가 있는데,
예를 들어 abs(-5) = 5 가 된다. x가 양수면 그대로, 음수면 "부호만 바꾸고" 양수로 만드는 함수.
abs(x) 를 비트 최적화 하면,, (x ^ (x>>31)) - (x>>31) 로 조건문 없이 부호제거가 되는데..풀어서 설명해보자면
x>>31
의 경우 32비트 정수 기준
0000 0000 0000 0000 0000 0000 0000 0000 로 갯수 상상,
양수면 오른쪽으로 31칸 가면서 모든 비트가 0 ,
음수면 오른쪽으로 31칸 가면서 모든 비트가 1 즉 -1, (2진수에서 가장 왼쪽 비트(MSB, Most Significant Bit)가 부호(sign) 비트 역할을 하기때문에 가장 왼쪽이 1이면 음수라고 인식한다. 부호가 있는 비트 기준이다.) ,
x^(x>>31)
의 경우
양수면 x^0 = x ( x가 어떤 수이든, 양수일경우 x>>31은 0이었다. 그러므로 어떤것이든 8비트로 축약 예를들어 0000 0000과 비교한다면.. x에 있는 0들은 걍 0이겠고, x에 1이있다면 x>>31에는 없을테니, 서로 다르기 때문에 1을 연산한다. 결국.. 그냥 x와 같은 값이 된다)
음수: x^ 0xffffffff = 비트반전 ( 음수일경우 x>>31이면 8비트로 축약 예를들었을때 1111 1111일텐데, x ^ (x>>31)은 따라서 x에서 0인 비트와 x>>31에서 1인것만 체크 후 1로 연산할 것이다. 이렇게 되면 비트가 모두 뒤집혀서(반전) 될것이다. 그랬을때 절대값|x|-1 의 10진수 값이 나올것이다. 예를들어 -5였다면 4가 나올 것 이다.)
여기에다가,
- (x>>31)
양수면 0의 값을 빼주고
음수면 -1의 값을 빼준다.
이러한 과정을 밟아서
abs(x) 는 (x^(x>>31)) -(x>>31) 과 같지만 비트연산인 (x^(x>>31)) -(x>>31) 가 더 효율적이다라는 사실을 알았다!
음수 표현 방법은 이러하다.
1. 절대값의 이진수 구하고
2. 비트반전 하고 (0 <-> 1)
3. +1 하면 된다.
예를 들어 -5를 8비트로 표현하려면,
1. +5는 0000 0101 이다.
2. 비트반전시 1111 1010 이다.
3. 여기에 끝에서 +1 하면 (만약 이미 끝에가 1이 있는 숫자라면, 2가 될수없고 다음 칸으로 넘어가면서 올리면 된다.)
1111 1011 이다. 이것이 -5이다.
그러면 비트연산은 언제 도대체 쓰는것인가?
아직 관련 지식이 많이 필요하지만 gpt 에게 물어보니 이러하다.
✅ 언제 직접 쓰면 좋을까?
| Unity LayerMask | ✅ | 엔진 API가 비트마스크 기반 |
| Enum Flags | ✅ | 상태 관리가 깔끔해짐 |
| 네트워크 메시지 직렬화 | ✅ | 대역폭 절약 |
| 단순 수치 곱셈(x×2ⁿ) | ❌ | 컴파일러가 자동 최적화 |
| 복잡한 수학 → 비트연산 대체 | ❌ | 가독성↓, 필요할 때만 |
🚀 결론
“게임 로직(상태·충돌·네트워크)” 에선 자주,
“수학 최적화” 차원에서는 드물게 비트 연산을 쓴다.
용도 예시 왜 비트 연산? 코드 예시
| Collision & LayerMask | 플레이어 ↔ 벽, 적, 아이템 충돌 분리 | 충돌 대상 그룹을 비트마스크로 빠르게 검사 | `LayerMask mask = 1<<8 |
| State Flags | 캐릭터 상태(달리기·점프·사격·피격) | 여러 Boolean 값을 하나의 정수에 저장해서 메모리 절약·비교 빠름 | [Flags] enum State { Idle=0, Run=1, Jump=2, Shoot=4 } `state |
| 네트워크 패킷 압축 | 위치·회전·이동 입력 데이터 송수신 | 데이터를 작은 바이트로 묶어 전송량 감소 | `byte flags = (byte)((isJump?1:0) |
당장은... 봐도 어디에 어떻게 쓰인다는건지 뭔소리인지는 잘모르겠다만 공부하다보면 알게될 것이라 생각하고 기록한다.
3. 학습하며 겪었던 문제점 & 에러
- 문제&에러에 대한 정의
- 내가 한 시도 - 해결 방법
- 새롭게 알게 된 점
- 이 문제&에러를 다시 만나게 되었다면?
4. 내일 학습 할 것은 무엇인지
C# 문법 기초 추가 복습, 정리
기초 수학공부
'Unity 개발 공부' 카테고리의 다른 글
| [내일배움캠프 사전캠프] 4일차 C# 캐스팅, 제어문, 반복문 프로그래밍 연습. (25.03.26) (1) | 2025.03.26 |
|---|---|
| [내일배움캠프 사전캠프] 3일차 C# 문법기초 클래스, 함수, 변수 파헤치기 (25.03.24) (0) | 2025.03.24 |
| [내일배움캠프 사전캠프] 3일차 C# 문법기초 제어문,배열, 함수, 클래스와 객체 (25.03.24) (0) | 2025.03.24 |
| [내일배움캠프 사전캠프] 1일차 C# 사전문법 기초 공부 - 변수 (0) | 2025.03.20 |
| [내일배움캠프 사전캠프] 0일차 시작. Unity 조사하기 (0) | 2025.03.19 |