[C#] 3. 오버플로우 & 언더플로우

치치·2024년 11월 19일
0

C#

목록 보기
3/16
post-thumbnail

📌 여러가지 자료형들

  • 1byte당 8비트
  • 1 byte의 범위 : -128 ~ +127 ( 1000 0000 ~ 0111 1111)
자료형크기값 범위
sbyte1 byte-128 ~ +127
byte1 byte0 ~ 255
short2 bytes-32,768 ~ +32,767
ushort2 bytes0 ~ 65,535
int4 bytes-2,147,483,648 ~ +2,147,483,647
uint4 bytes0 ~ 4,294,967,295
long8 bytes-9,223,372,036,854,775,808 ~ +9,223,372,036,854,775,807
ulong8 bytes0 ~ 18,446,744,073,709,551,615
float4 bytes±1.5 × 10^-45 ~ ±3.4 × 10^38
double8 bytes±5.0 × 10^-324 ~ ±1.7 × 10^308
decimal16 bytes±1.0 × 10^-28 ~ ±7.9 × 10^28 (28~29 자릿수)
char2 bytesUnicode 0 ~ 65,535
bool1 byte(*)true / false
  • int & float는 같은 4바이트여도 float가 더 큼

📌 오버플로우란?

  • 특정한 자료형이 표현할 수 있는 최댓값의 범위를 넘어서 연산을 수행하는 과정

  • 오버플로우는 부호 없는 자료형에서도 똑같이 발생

  • C#에서는 발생x

ex)

  • sbyte 자료형1byte = 8 bit
  • 범위는 -128 ~ +127
  • 만약에 [01111111] = 127에서 1을 더하게 된다면?
  • -> 넘어서서 -128이 됨 (부호비트가 음수가 된다)

📌 언더플로우란?

  • 특정한 자료형이 표현할 수 있는 최솟값의 범위를 넘어서 연산을 수행하는 과정
  • 언더플로우는 부호 없는 자료형에서도 똑같이 발생하며, 최솟값보다 더 작은 값으로 저장하게 되면 최댓값부터 다시 최솟값을 넘어간 만큼 다시 계산

ex)

  • sbyte 자료형은 1byte = 8 bit
  • 범위는 -128 ~ +127
  • 만약에 [10000000] = -128에서 1을 뺀다면?
  • -> 넘어서서 127이 됨 (부호비트가 양수가 된다)


📌 부호 없는 자료형

  • unsigned의 약자인 u를 붙이면 부호 없는 자료형이 된다. C++에서는 unsigned
    ➡ 부호가 없는 만큼 -범위의 값 만큼 더 커지는 것.
    ex) ushort, uint, ulong . . .

원래의 short 범위 : -32768 ~ + 32767
ushort 범위 : 65535 ~ 0

ushort money = 65535;

Console.WriteLine(money);

결과값 : 65535;

최대값: 32,768 + 32,767 = 65535
최솟값: 0

⭐ sbyte & byte

sbyte : 부호 있는 자료형 (-128 ~ +127)
byte : 부호 없는 자료형 (0 ~ 255)
byte의 경우도 부호가 없기 때문에 sbyte의 - 범위를 모두 합친 범위가 된다.



📌 자료형 변환 (캐스트)

서로 다른 자료형을 가지고 있는 변수끼리 연산이 이루어 질 때 기존에 지정했던 자료형을 다른 자료형으로 변환하는 과정
크기가 더 큰 자료형이 작은 자료형을 담을 수 있다.

🔒 암묵적 형 변환

  • 서로 다른 자료형으로 연산이 이루어질 때, 자료형의 크기가 큰 자료형으로 변환되는 과정
  • int형과 long형이 연산하게 되면 암묵적 형 변환에 의해 크기가 더 큰 long타입으로 변수에만 담을 수 있게된다.
int a = 100;	 // 4바이트
long b = 100;	 // 8바이트
long sum = a + b;

출력값 : 200

🔒 명시적 형 변환

  • 연산이 이루어지기 전에 사용자가 직접 자료형을 변환하는 과정
int attack = 10;
int defense = 3;
float damage = (float)attack / defense;
Console.WriteLine("damage 변수의 값 : " + damage);

출력값 : 3.333333

⭐ 다양한 타입 형 변환 Convert

다양한 타입을 인자로 받을 수 있고, 다양한 타입으로 변환이 가능하다.

Convert.ToInt32(...);
Convert.ToSingle(...);
Convert.ToBoolean(...);
Convert.ToString(...);
string s = "123";
int n = Convert.ToInt32(s);  // 결과: 123

bool isDead = true;
int val = Convert.ToInt32(isDead);  // 결과: 1 (false면 0)

int n = 999;
string s = Convert.ToString(n);  // 결과: "999"

❗ 숫자 ➡ 문자 ToString()

➡ 유니티의 UI에 숫자를 출력하기 위해 많이 사용해본 것이다.
실제 형변환은 아니고, 문자열로 표현할 수 있게 하는 함수이다.
❗ 형변환(캐스트)와는 다른 것!! ❗

int a = 100;
string b = a.ToString();
print(b); // "100" 출력

⭐ 문자열 ➡ 숫자 변환 Parse()

➡ 입력받은 문자열을 원하는 자료형으로 변환할 수 있다. (문자숫자만 가능)
ex) 원하는 자료형.Parse(문자열);

int a;
string b = "100";
a = int.Parse(b); // int a = 100 

string b = "ddsfsdf"; // 일 경우 오류 발생

⭐ 문자열 ➡ 숫자 변환 TryParse()

변환 실패해도 예외를 던지지 않고 false를 반환한다.

string s = "abc";
if (int.TryParse(s, out int result))
{
    Console.WriteLine(result);
}
else
{
    Console.WriteLine("변환 실패");
}

📌 as & is

⭐ 참조형 형 변환 as

실패 시 null을 반환한다. 참조형에서만 사용가능하다.
class, interface

object obj = "hello";
string s = obj as string; // 성공 시 "hello", 실패 시 null

유니티에서 사용할 때 아래와 같이 사용할 수 있다.
comp변수가 SpriteRender타입이 맞다면 sr에 할당한다. 즉, null이 아니게 된다.

void Start()
{
    Component comp = GetComponent<SpriteRenderer>();
    // 안전한 캐스팅
    SpriteRenderer sr = comp as SpriteRenderer;
    if (sr != null)
    {
        sr.color = Color.red;
    }
}

⭐ 형 확인 is

변환은 하지않고, 타입 체크용으로 사용한다.

object obj = "hello";
if (obj is string s)
{
    Console.WriteLine(s); // 형 확인 + 변환된 값 사용
}

유니티에서 사용할 때 아래와 같이 사용할 수 있다.

void Start()
{
    Component comp = GetComponent<SpriteRenderer>();
    if (comp is SpriteRenderer)
    {
        Debug.Log("이 컴포넌트는 SpriteRenderer입니다.");
    }
}

profile
뉴비 개발자

0개의 댓글