C#

C# Value Type : 값 형식 - 정수 숫자 형식

_dev_mu ㅣ 2023. 1. 12. 23:20

정수 숫자 형식은 정수를 표현합니다.
모든 정수 숫자 형식은 값 형식입니다.
간단한 형식이기도 하며 리터럴을 사용하여 초기화할 수 있습니다.
모든 정수 숫자 형식은 산술, 비트 논리, 비교 및 같음 연산자를 지원합니다.

 

정수 형식의 특성

C#은 다음과 같은 미리 정의된 정수 형식을 지원합니다.
C#  형식 키워드 범위 크기 .Net 형식
sbyte -128 ~ 127 부호 있는 8비트 정수 System.SByte
byte 0 ~ 255 부호 없는 8비트 정수 System.Byte
short -32,768 ~ 32,767 부호 있는 16비트 정수 System.Int16
ushort 0 ~ 65,535 부호 없는 16 비트 정수 System.UInt16
int -2,147,483,648 ~ 
2,147,483,647
부호 있는 32비트 정수 System.Int32
uint 0 ~ 4.294.967.295 부호 없는 32비트 정수 System.UInt32
long -9,223,372,036,854,775,808 ~
9,223,372,036,854,775,807
부호 있는 64 비트 정수 System.Int64
ulong 0 ~ 18,446,744,073,709,551,615 부호 없는 64비트 정수 System.UInt64
nint 플랫폼에 따라 다름 (런타임에 계산됨) 부호 있는 32 비트 또는
부호 있는 64 비트 정수
System.IntPtr
nuint 플랫폼에 따라 다름 (런타임에 계산됨) 부호 없는 32 비트 또는
부호 없는 64 비트 정수
System.UIntPtr
마지막 두 개를 제외한 모든 테이블 행에서 맨 왼쪽 열의 각 C# 형식 키워드는 해당하는 .NET의 별칭입니다.
키워드와 .NET 형식 이름은 서로 바꿔 사용할 수 있습니다.
int a = 123;
System.Int32 b = 123;
표의 마지막 두 행에 있는 nint 및 nuint 형식은 기본 크기 정수입니다.
C# 9.0부터 nint 및 nuint 키워드를 사용하여 기본 크기 정수를 정의할 수 있습니다.
이러한 정수는 32비트 프로세스에서 실행되는 경우 32비트 정수이고 64비트 프로세스에서 실행되는 경우 64비트 정수입니다.
이들은 상호 운용성 시나리오, 하위 수준 라이브러리에 사용할 수 있고 정수 연산이 광법위하게 사용되는 시나리오에서 성능을 최적화하는 데 사용할 수 있습니다.
기본 크기 정수 형식은 내부적으로 .NET 형식 System.IntPtr 및 System.UIntPt로 표시됩니다.
C# 11부터 해당 nint 형식과 nuint 형식은 기본 형식의 별칭입니다.
각 정수 형식의 기본값은 0입니다.
각 정수 계열 형식에는 MonValue 해당 형식의 최소값과 MaxValue 최대값을 제공하는 속성이 있습니다.
이러한 속성은 네이티브 크기 형식(nint 및 nuint)의 경우를 제외하고 컴파일 시간 상수 입니다.
MaxValue 및 MinValue 속성은 런타임에 네이티브 크기 형식에 대해 계산됩니다.
이러한 형식의 크기는 프로세스 설정에 따라 달라집니다.

System.Numerics.BigInterger 구조체를 사용하여 상한 또는 하한이 없는 부호 있는 정수를 나타냅니다.

 

정수 리터럴

정수 리터럴은 다음 형식일 수 있습니다.
1. 10 진 : 접두사가 없음
2. 16 진수 : 0x 또는 0x 접두사 사용
3. binary : 0b 또는 0B 접두사 사용
var decimalLiteral = 42;
var hexLiteral = 0x2A;
var binaryLiteral = 0b_0010_1010;
_  : 모든 종류의  숫자 리터럴에서 숫자 구분 기호를 사용할 수 있습니다. 
정수 리터럴의 형식은 접미사로 다음과 같이 결정됩니다.

1. 리터럴에 접미사가 없는 경우 해당 형식은 값이 표현될 수 있는  int, uint, long, ulong 형식 중 첫 번째 형식입니다.
리터럴은 양수 값으로 해석됩니다.
예를 들어 리터럴 0xFF_FF_FF_FF는 uint 형식의 숫자 4294967295를 나타내지만, int 형식의 숫자 -1과 같은 비트를 표현합니다.
특정 형식의 값이 필요한 경우 리터럴을 해당 형식으로 캐스팅합니다.
리터럴 값을 대상 유형으로 표현할 수 없는 경우 unchecked 연산자를 사용합니다.
예를 들어 unchecked((int)0xFF_FF_FF_FF)는 -1을 생성합니다.
2. 리터럴에 접미사가 U 또는 u인 경우 해당 형식은 값이 표현될 수 있는 uint, ulong 형식 중 첫 번째 형식입니다.
3. 리터럴에 접미사가 L또는 l인 경우 해당 형식은 값이 표현될 수 있는 long, uling형식 중 첫 번째 형식입니다.
4. 리터럴의 접미사가 UL,Ul,uL,LU,Lu,lU 또는 lu이면 해당 형식은 ulong입니다.
정수 리터럴로 표시되는 값이 UInt64.MaxValue를 초과하면 컴파일 오류 CS1021이 발생합니다.

결정된 정수 리터럴 형식이 int 이고 리터럴이 나타내는 값이 대상 형식의 범위 내에 있는 경우, 해당 값이 암시적으로 sbyte, byte, short  ushort, uint, ulong, nint 또는 nuint으로 변환 될 수 있습니다.
byte a = 17;
byte b = 300;   // CS0031: Constant value '300' cannot be converted to a 'byte'

// 앞의 예제와 같이 리터럴의 값이 대상 형식의 볌위 내에 있지 않으면 컴파일러 오류 CS0031이 발생합니다.
캐스트를 사용하여 정수 리터럴로 표시되는 값을 결정된 리터럴 형식 이외의 형식으로 변환할 수도 있습니다.
var signedByte = (sbyte)42;
var longVariable = (long)42;

 

변환

모든 정수 숫자 형식을 다른 정수 숫자 형식으로 변환할 수 있습니다.
대상 형식이 소스 형식의 모든 값을 저장할 수 있는 경우 변환은 암시적입니다.
저장할 수 없는 경우에는 캐스트 식을 사용하여 명시적 변환을 수행해야 합니다.

 

원시 크기 정수

스토리지는 대상 컴퓨터의 자연 정수 크기에 따라 결정되므로 네이티브 크기의 정수 형식은 특별한 동작을 갖습니다.
런타임에 기본 크기 정수의 크기를 가져오려면 sizeof()를 사용할 수 있습니다.
그러나 안전하지 않은 컨텍스트에서 코드를 컴파일해야 합니다.
Console.WriteLine($"size of nint = {sizeof(nint)}");
Console.WriteLine($"size of nuint = {sizeof(nuint)}");

// output when run in a 64-bit process
//size of nint = 8
//size of nuint = 8

// output when run in a 32-bit process
//size of nint = 4
//size of nuint = 4
런타임에 기본 크기 정수의 최소값 및 최대값을 가져오려면 다음 예제와 같이 MinValue 및 MaxValue 를 nint  및 nuint 키워드를 포함하는 정적 속성으로 사용합니다.
Console.WriteLine($"nint.MinValue = {nint.MinValue}");
Console.WriteLine($"nint.MaxValue = {nint.MaxValue}");
Console.WriteLine($"nuint.MinValue = {nuint.MinValue}");
Console.WriteLine($"nuint.MaxValue = {nuint.MaxValue}");

// output when run in a 64-bit process
//nint.MinValue = -9223372036854775808
//nint.MaxValue = 9223372036854775807
//nuint.MinValue = 0
//nuint.MaxValue = 18446744073709551615

// output when run in a 32-bit process
//nint.MinValue = -2147483648
//nint.MaxValue = 2147483647
//nuint.MinValue = 0
//nuint.MaxValue = 4294967295
nint : Int32.MinValue ~ Int32.MaxValue.
nuint : UInt32,MinValue ~ UInt32.MaxValue.
컴파일러는 다른 숫자 형식으로 암시적 변환과 명시적 변환을 제공합니다.
기본 크기 정수 리터럴에 대한 직접 구문은 없습니다.
L이 long을 나타내는 것과 같이 리터럴이 기본 크기 정수임을 나타내는 접미사는 없습니다.
대신 다른 정수 값의 암시적 또는 명시적 캐스트를 사용할 수 있습니다.
nint a = 42
nint a = (nint)42;