개발자

비트연산관련 질문입니다.

2024년 07월 12일조회 84

우연히 비트관련해서 끄적이다 발견했습니다. 먼저 0x8000을 2바이트 short(golang에서는 int16)형 변수에 16진수 0x8000(앞에 형변환 넣었습니다.)을 할당 하면 제가 원한 결과인 -32768가 아닌 컴파일러에서는 양수로 인식이 되고 런타임(디버깅 모드, 브레이크 포인트잡고)에선 원하는 결과인 -32768이 반환되는데요 혹시 어떤 이유에서 컴파일러는 오류라 판단하는 건가요? 2의 보수에 의해 이런 결과가 나오는 건가요?

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.

답변 1

장성호님의 프로필 사진

자바는 기본적으로 정수 리터럴을 int 타입으로 간주해요. 지금은 short 타입을 사용하셨으니 기본적으로 -32768 ~ 32767 범위에서는 short 타입으로 간주합니다. 하지만 0x8000은 32768 이기 때문에 short 타입을 벗어나므로, int 타입으로 간주해 컴파일러는 양수로 인식합니다. 런타임에서는 short로 타입 캐스팅을 하기 때문에 오버플로우가 발생해 -32768이란 값으로 나오는 겁니다. 위처럼 생각하고 있으나 언어마다 컴파일러가 어디까지 커버쳐줄지는 다르기 때문에, js나 go는 또 어떨지 모르겠네요ㅎㅎ 사진만 봐서는 js나 go 컴파일러는 범위 넘는 순간 오버플로우 / 언더플로우를 컴파일 오류로 잡는 것 같군요. 자바는 그냥 있을 수 있는 현상으로 보는 거구요. 아니면 IDE 혹은 플러그인이 지원해주는 기능이거나

오준영(Jeremy Oh)님의 프로필 사진

오준영(Jeremy Oh)

작성자

목원대학교 컴퓨터 공학2024년 07월 18일

C#문서를 뒤적여보다 리터럴은 양수 값으로 해석이 된다고 나오네요 만약 음수표현을 원하면 unchecked문을 사용하라는 설명도 있었고요!! 자바의 경우는 리터럴은 기본적으로 정수형으로 간주한다고 말씀해주셔서 언어별로 이런 차이가 있는줄은 몰랐습니다. 도움주신 덕분에 해결을 할수 있었습니다! 오늘 비도 많이 오는데 퇴근길에 비때문에 고생이 없으시길 바라요! 행복한하루 보내세요!

장성호님의 프로필 사진

장성호

Toss Server Developer2024년 07월 18일

그새 C# 까지 찾아보셨군요. 공부할 때 폴리글랏은 좋은 태도인 것 같아요. 이런 사소한거 하나 하나 언어마다 다르다는거 알게 되다보면 시야가 넓어지는 게 느껴지거든요. unchecked 문을 그럼 자바나 js, go 같은데선 못쓰나? 하다 보면 뜬금없이 자바 어노테이션으로 주제가 확장되고 그러기도 합니다.

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2024년 07월 12일

비트 연산에 관한 궁금증이 있으신 것 같네요. 먼저, `0x8000` 이라는 16진수는 2진수로 변환하면 `1000000000000000` (16개의 비트)입니다. short나 int16 자료형은 메모리에서 16비트를 차지합니다. 하지만, 첫 번째 비트는 흔히 "부호 비트"라고 부르며 양수와 음수를 구분하는데 사용됩니다. 첫 번째 비트가 1이면 음수, 0이면 양수를 나타냅니다. `0x8000`을 음수로 해석하면 이진 법칙에 따라 `-32768`이 됩니다. 반면에 양수로 해석하면 `32768`이 됩니다. 왜 IDE에서 컴파일러가 다르게 동작하는지는 환경과 설정에 따라 다릅니다. 특히, 언어별로 정체 및 판독 방식에 미세한 차이가 있을 수 있습니다. 여기서 중요한 점은 변수에 값을 할당할 때 형변환이 필요하고, 본질적으로 `0x8000`은 단순히 숫자일 뿐인데, 그것이 양의 int16으로 인식되거나 음의 int16으로 인식되는 것은 언어나 컴파일러의 특성에 따라 다르다는 것입니다.

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!