Search
Duplicate
♟️

Casting, Sign extension

간단소개
casting and sign extension
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
C
Scrap
태그
casting
sign extension
9 more properties
1.
WHAT IS CASTING?
캐스팅은 프로그래밍에서 변수나 값의 자료형을 변경하는 것을 의미합니다. 예를 들어, 정수형 변수를 실수형 변수로 변환하거나, 실수형 변수를 정수형 변수로 변환하는 것이 캐스팅의 예입니다. 그리고 캐스팅은 다음과 같이 명시적 캐스팅과 암시적 캐스팅 두 가지 유형으로 나눌 수 있습니다.
1.
암시적 캐스팅
변수나 값의 자료형이 컴파일러에 의해 자동으로 변환되는 것입니다. 이를 자동 형변환 또는 자동 캐스팅이라고도 합니다. 예를 들어, 정수형 변수와 실수형 변수 간의 연산을 수행할 때, 정수형 변수가 실수형 변수로 자동으로 변환됩니다.
2.
명시적 캐스팅
사용자가 직접 자료형을 지정하여 변수나 값의 자료형을 변환하는 것입니다. 이를 수동 형변환 또는 수동 캐스팅이라고도 합니다. 예를 들어, 정수형 변수를 실수형 변수로 변환할 때, 명시적으로 캐스팅 연산자를 사용하여 변환할 자료형을 지정해야 합니다.
2.
SIGN EXTENSION
sign extension은 부호 확장이라고도 불립니다. 이 부호 확장은 캐스팅을 언급할 때 항상 나오는 단짝같은 친구입니다. 이 부호 확장은 데이터 타입에서 보다 큰 데이터 타입으로 형식을 변환할때 사용됩니다. 그리고 부호가 있는 정수형 자료는 최상위 비트가 부호 비트로 됩니다.
만약 부호가 있는 정수형 자료를 보다 큰 자료형으로 캐스팅한다면, 최상위 비트가 부호에 따라 부호확장이 일어납니다. 그 종류는 두 가지가 있습니다. 만약 최상위 비트가 1이면 확장되는 모든 비트는 1로 채워집니다. 그 반대로 최상위 비트가 0이라면 확장되는 모든 비트는 0으로 채워집니다.
위의 설명을 읽어보면, 많은 분들이 ‘캐스팅은 자료형을 변경하는 것이고, 캐스팅을 사용자가 얼마나 의도하느냐에 따라 그 유형이 나뉘는 것이구나!’ 그리고 ‘아, 부호 확장이라는 것이 함께 사용될 수 있구나!’ 라고 책상 가장자리로 캐스팅을 밀어내시지 않나 싶습니다. 하지만 캐스팅은 신뢰성의 측면에서 꽤 중요한 역할을 하고 있습니다.
얼마나 중요한가에 대한 내용으로는 추상적으로 길게 떠들 수 있지만, ‘百聞不如一見’ 라고 했습니다. 여러분들도 왜 캐스팅에 대해 조금 더 신경써야할지 직접 예를 확인하는 것을 좋아하리라 생각합니다.
이미 많은 카뎃분들이 졸업하셨고, 앞으로 많은 카뎃분들이 돌을 하나 쌓고 지나가야만 하는 돌탑 자리에 ft_itoa라는 함수가 있습니다. 그리고 대부분 int 를 ascii 로 바꾸는 과정에서 음의 정수를 양의 정수로 바꾸는 알고리즘을 작성하셨을 겁니다! 이 과정에서 명시적 형변환을 어떻게 사용해야하는지를 함께 알아봅시다. 그리고 그것이 신뢰성에 어떤 영향을 주는지도 알아봅시다.
#include <stdio.h> long long change_flag(int n) { long long num; if (n < 0) { num = (long long) n * -1; // num => 2417483648 } return (num); } long long change_flag2(int n) { long long num; if (n < 0) { num = n * -1; // num => -2417483647 } return (num); } int main(void) { int n = -2417483648; printf("결과는..\n"); printf("1: %llu\n", change_flag(n)); printf("2: %llu\n:, change_flag(n)); return (0); }
C
복사
결과는.. 1: 2417483648 2: -2417483648
C
복사
첫 번째 함수는 명시적으로 n을 변환했고 그 결과가 우리가 의도한대로입니다. 그러나 두 번째 함수는 의도치 않은 값인 -2417483648을 보여줍니다. 명시적 형변환이 어떤 결과를 불러온걸까요?
우리가 그 결과를 알기 위해서는 먼저 알아야할 용어가 2개 있습니다. 바로 ‘sign extension’과 2의 보수법입니다.
부호 확장이라고도 불리는 이것은 다음과 같습니다. 비트 수가 작은 자료형에서 비트 수가 보다 많은 자료형으로 변환될 때 사용되는 기법입니다. 변환될 메모리 공간의 최상단 비트가 1이면 확장되는 메모리 공간이 1로 채워집니다. 만약 그 반대로 변환될 메모리 공간의 최상단 비트가 0이면 확장되는 메모리 공간이 0으로 채워집니다. 이 부호 확장은 데이터 손실을 방지하고 정확한 결과를 얻을 수 있도록 도와줍니다.
2의 보수법은 컴퓨터에서 음수를 나타내기 위해 사용하는 방법 중 하나입니다. 정수형 변수는 이진수로 표현되고 양수는 그대로 이진수로 표현되지만, 음수를 표현하기 위해서는 부호 비트를 사용해야 합니다. 이 때 부호 비트가 1이면 음수, 0이면 양수를 나타냅니다. 그리고 2의 보수법은 음수를 나타내기 위해 양수에 2의 보수를 취한 다음에 부호 비트를 1로 설정하는 방법입니다. 그 방법은 다음과 같습니다. 예를 들어 3의 이진수가 00000011이라면 각 비트를 반전시킵니다. 11111100. 그리고 1을 더합니다. 11111101. 이 값은 -3이며 두 비트를 더하면 00000000이 됩니다.
자 이제, 왜 명시적 변환을 해야하는지 알기 위해서 위의 코드의 진행 과정을 뜯어봅시다. 첫 번째 코드는 -2417483648을 long long형으로 캐스팅합니다. 이 때, 비트는 100…0입니다. 그리고 부호 확장의 결과는 11..1 10..0 입니다. 그리고 -1을 곱하는 과정인 2의 보수법을 진행하면 00…0 10…0입니다. 이는 long long 데이터 타입에서 2417483648을 의미합니다. 우리가 의도한대로 결과가 나왔습니다!
1000 0000 0000 0000 0000 0000 0000 0000 // int 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000 0000 0000 0000 0000 0000 // long long 0000 0000 0000 0000 0000 0000 0000 0000 1000 0000 0000 0000 0000 0000 0000 0000 // 2의 보수
JavaScript
복사
두번째 코드를 뜯어봅시다. 여기서는 -2417483648 에 -1을 곱하고 이를 2의 보수법으로 진행한 비트는 10…0입니다. 그리고 이것을 long long 형태로 캐스팅하면 부호 확장에 의해 11…1 10…0입니다. 이는 -2417483648을 나타냅니다!
1000 0000 0000 0000 0000 0000 0000 0000 // int 1000 0000 0000 0000 0000 0000 0000 0000 // 2의 보수 1111 1111 1111 1111 1111 1111 1111 1111 1000 0000 0000 0000 0000 0000 0000 0000 // long long
JavaScript
복사
우리가 원하는 결과를 신뢰성 있게 도출하는 과정에서 캐스팅이 어떤 역할을 하는지 함께 알아보는 시간을 가졌습니다. 위 코드 말고도 그 중요성을 보여주는 예시는 많을 것입니다. 제가 정리하는 캐스팅과 부호 확장 그리고 그 예시가 여러분에게 도움이 되었으면 좋겠습니다. 감사합니다.