Introduction
암시적 변환
정수 형식 | 변환 가능 형식 |
---|---|
sbyte | 정수 : short , int , long , nint 실수 : 모든 실수 형식 |
byte | 정수 : short , ushort , int , uint , long , ulong , nint , nuint 실수 : 모든 실수 형식 |
short | 정수 : int , long , nint 실수 : 모든 실수 형식 |
ushort | 정수 : int , uint , long , ulong , nint , nuint 실수 : 모든 실수 형식 |
int | 정수 : long , nint 실수 : 모든 실수 형식 |
uint | 정수 : long , ulong , nuint 실수 : 모든 실수 형식 |
long | 실수 : 모든 실수 형식 |
ulong | 실수 : 모든 실수 형식 |
nint | 정수 : long 실수 : 모든 실수 형식 |
nuint | 정수 : ulong 실수 : 모든 실수 형식 |
실수 형식 | 변환 가능 형식 |
---|---|
float | 실수 : double |
모든 정수 형식은 실수 형식으로 암시적 변환이 가능하다.
다른 형식의 값 범위 내에 있는 경우,
int
형식의 상수 식 값 (정수 리터럴, const 한정자) 은 다른 숫자 형식으로 암시적 변환이 가능하다.const int X = 500; float Y = X; byte Z = X; // CS0031: '500' 상수 값을 'byte`(으)로 변환할 수 없습니다.
다음 변환의 경우 정밀도 손실 가능성이 있다. (자릿수 손실은 없다)
형식 변환 형식 int
,uint
,long
,ulong
,nint
,nuint
float
long
,ulong
,nint
,nuint
double
명시적 변환
- 아래 표는 암시적 변환은 불가하지만 명시적 변환이 가능한 형식에 대한 표이다.
정수 형식 | 변환 가능 형식 |
---|---|
sbyte | 정수 : byte , ushort , uint , ulong , nuint |
byte | 정수 : sbyte |
short | 정수 : sbyte , byte , ushort , uint , ulong , nuint |
ushort | 정수 : sbyte , byte , short |
int | 정수 : sbyte , byte , short , ushort , uint , ulong , nuint |
uint | 정수 : sbyte , byte , short , ushort , int , nint |
long | 정수 : sbyte , byte , short , ushort , int , uint , ulong , nint , nuint |
ulong | 정수 : sbyte , byte , short , ushort , int , uint , long , nint , nuint |
nint | 정수 : sbyte , byte , short , ushort , int , uint , ulong , nuint |
nuint | 정수 : sbyte , byte , short , ushort , int , uint , long , nint |
실수 형식 | 변환 가능 형식 |
---|---|
float | 정수 : 모든 정수 형식 실수 : decimal |
double | 정수 : 모든 정수 형식 실수 : float , decimal |
decimal | 정수 : 모든 정수 형식 실수 : float , double |
정수 형식의 명시적 변환
- 정수 형식의 값을 다른 정수 형식으로 명시적 변환하는 경우 결과는 컨텍스트에 따라 달라진다.
checked 컨텍스트 : 변환 형식 값 범위 내에 있다면 성공, 밖에 있다면 OverflowException 발생
unchecked 컨텍스트 : 항상 성공하지만 올바르지 않은 값으로 변환될 수 있다.
원본 형식의 크기가 변환 형식보다 큰 경우 : 원본 형식의 앞쪽 비트를 잘라 변환 형식의 비트 길이에 맞춘다. 이후 남은 비트를 변환 형식의 값으로 처리한다.
long testLong = 8428608; // 80 9C40, 8,428,608 short testShort = unchecked((short)testLong); // 9C40, -25536
원본 형식의 크기가 변환 형식보다 작은 경우 : 비트 처리 과정은 아래 두 케이스에 따라 달라진다. 이후 변환 형식의 값으로 처리한다.
Signed type : 부호 확장을 한다.
- 부호 확장 : 원본 형식의 가장 앞 비트를 확장하는 비트에 전부 할당한다.
short testShort = -500; // FE0C, -500 uint testUInt = unchecked((uint)testShort); // FFFF FE0C, 4,294,966,796
- 부호 확장 : 원본 형식의 가장 앞 비트를 확장하는 비트에 전부 할당한다.
Unsigned type : 제로 확장을 한다. 이 경우는 C#에서는 별로 신경 안써도 괜찮다.
- 제로 확장 : 확장하는 비트에 0을 전부 할당한다.
ushort testShort = 40000; // 9C40, 40000 int testInt = unchecked((int)testShort); // 9C40, 40000
- 제로 확장 : 확장하는 비트에 0을 전부 할당한다.
원본 형식과 변환 형식의 크기가 같은 경우 : 변환 형식의 값으로 처리한다.
실수 형식의 명시적 변환
실수 -> 정수 형식 변환
정수 형식으로 변환하는 경우 소수점 자리 반올림 오류가 발생할 수 있다. (기본적으로 버림 처리한다)
double castingDouble = 1.6; int castingInt = (int)castingDouble; // castingInt = 1 double castingDouble2 = 1.5; int castingInt2 = (int)Math.Round(castingDouble2); // castingInt2 = 2
또한, 변환할 형식 값의 범위를 벗어나는 경우에는 원본 형식의 타입과 컨텍스트에 따라 처리된다.
decimal
: 컨텍스트 (checked
,unchecked
) 에 관계 없이 OverflowException이 발생한다.float
,double
:checked
컨텍스트에서만 OverflowException이 발생한다.unchecked
컨텍스트에서는 변환하는 정수 형식의 unspecified value를 갖게 된다.
float
형식을int
또는uint
형식으로 변환하는 경우, 최대값을 넘지 않더라도 근처에서는 의도치 않은 동작이 발생할 수 있다.
이는 IEEE Standard 754에 정의된float
데이터형에 의한 것이다.
실수 -> 실수 형식 변환
double
을float
으로 변환하는 경우 :float
형식에 맞게 반올림된다.- 만일
double
값이float
으로 표현하기에 너무 작거나 큰 경우,0
또는∞
로 처리된다.
float
또는double
을decimal
로 변환하는 경우 :decimal
형식에 맞게 반올림된다.- 만일 원본 값이
decimal
로 표현하기에 너무 작은 경우에는0
으로 처리된다. - 만일 원본 값이
NaN
,∞
또는decimal
로 표현하기에 너무 큰 값인 경우에는 OverflowException이 발생한다.
decimal
을float
또는double
로 변환하는 경우 :- 변환하는 형식에 맞게 반올림된다.