int 와 unsigned의 차이

clapmin의 이미지

질문 1
제가 알기로는 둘다 4byte라고 알고 있는데, 어제 제가 누군가와 이야기를 하다가 int를 unsigned로 바꾸게 되면 문제를 해결할 수 있다고 말했더니, 상대방이 하는말이 "unsigned int로 바꾸면 약~~~~~간 용량을 더먹기는 하지만...." 이라고 말했는데, 전 둘다 같은 크기라고 생각했는데 그게 아닌가요?

질문 2
만약
int a = int_max; // int 최대값
int res = 0;

res = (a+ 1) / 2
라는 형태의 코드가 있는경우
저는 a + 1은 int가 저장 할 수 있는 값보다 크지만 /2연산 후에 res에 저장하기 때무네 overflow가 발생하지 않을거라고 생각했는데, a + 1 에서 바로 overflow가 난다고 하더군요..... 이부분도 설명좀 부탁드립니다.

- 왜 overflow가 나는건지?
- 어떤 방식으로 이 상황을 방지하는지( unsigned int // casting... 등등)

clapmin의 이미지

네 int 크기는 상황에 따라 다를 수 있지만
제가 질문드린거는 같은 환경에서 int 와 unsigned int의 크기가 다를 수 있는가에 대해 여쭤본겁니다.

댓글 감사합니다!!

 의 이미지

1. 의문의 여지 없이 질문자님이 "상대방"보다 옳으십니다. 단 질문자님도 절반만 맞으셨습니다.

C언어 표준에서는 int 타입의 크기를 구체적으로 명시하지 않습니다. 이 타입이 -32767 이상 +32767 이하의 수를 나타낼 수 있어야 한다고 명시할 뿐입니다. 실제로 16비트 시절 쓰던 컴파일러들을 구해서 사용해 보면 int를 16비트 정수형으로 지정한 경우를 보게 되는데, 이들은 여전히 표준을 준수하는 것입니다. 물론, 지정된 범위보다 더 넓은 범위를 표현하게 만드는 것도 허용되므로, 현대 거의 대부분의 x86-32 및 x86-64 컴파일러들은 int를 32비트 정수형으로 지정하고 있습니다. 언젠간 64비트로 바뀔지도 모르는 일이고, 그렇게 해도 역시 표준에 부합합니다.

반면에 intunsigned int의 크기 대소관계에 대해서는 C언어 표준이 아주 뚜렷하게 명시해 놓고 있습니다. 표준문서의 일부를 발췌하니 "상대방"과의 논쟁에 도움이 되길 바랍니다. :)

C11 standard 6.2.5.6 wrote:
For each of the signed integer types, there is a corresponding (but different) unsigned integer type (designated with the keyword unsigned) that uses the same amount of storage (including sign information) and has the same alignment requirements. (the rest omitted)

네, 똑같답니다.

2. 간단합니다. a+1int 타입인데, int타입이 표현할 수 있는 범위를 넘어섰기 때문이지요.

변수에 저장될 때에만 타입을 가지는 게 아닙니다. 그리고 변수에 저장될 때에만 오버플로우가 일어나는 것도 아닙니다.
변수의 저장되기 전에 표현식의 일부일 때도 타입을 가지고 그 타입의 표현범위를 넘어서면 오버플로우가 일어납니다.

따라서, 오버플로우가 일어나는 것을 막기 위해서는 계산의 모든 과정에서 각각 그 시점에서의 타입 표현 범위를 넘지 않게 컨트롤해 줘야 합니다. 네. 표현식이 복잡해질수록 귀찮아집니다.

게다가 사실 C언어에서 정수 산술 연산의 타입이라는 게 썩 그렇게 간단하지만도 않아요. C언어 표준을 보면 integer conversion rankinteger promotions이니 Usual arithmetic conversions이니 하면서 왱알왱알대는데 진짜 설명하기 귀찮습니다.

어떻게 하면 제시된 코드를 overflow를 피해서 프로그래머의 의도에 맞게 작성할 수 있을 것인가. 사실 저도 처음엔 좀 쉽게 생각했어요. ((unsigned int)a) + 1 정도면 될 거라고 생각했죠. 이러면 결과 타입이 unsigned int가 되는데, 그 이유는 위에서 귀찮아서 설명을 생략했습니다. ㅎ

근데 그거 아세요? int가 표현가능한 수의 최대값인 INT_MAX보다 1 큰 수를 unsigned int로 표현가능하다는 보장이 표준에 없습니다. 저도 방금 찾아보고 알았네요. -_-;;;

표준을 엄격히 따지면서 코딩하면 발이 묶이는 기분이에요. 아무튼, 그래도 어떻게든 하려면 할 수는 있죠. 이렇게 하는 건 어때요?

res = (a == INT_MAX)?((INT_MAX/2)+(INT_MAX&1)):((a+1)/2);

좀 필요 이상으로 방어적으로 작성한 감이 있긴 합니다만, 표준 운운하면서 코딩할 때 실수하는 것처럼 아이러니한 경우가 잘 없거든요. 물론 이렇게 조심해서 짜도 간혹 실수가 나옵니다. 다 제가 모자란 탓이죠.

clapmin의 이미지

사실 1번 문제가 회사 면접에서 나왓던 이야기 인데(어디인지는 말씀드리기가 곤란 ㅎ;;) 말씀해주신 분이 경력 10년 정도 되는 현직자 셨는데, 취업이 되서 나중에 왜 그렇게 말하셨는지 물어볼 기회가 있으면 좋겠네요 ㅎㅎ

2번 문제는 설명을 잘해주셔서 한번에 이해 했습니다!!
하지만 "int가 표현가능한 수의 최대값인 INT_MAX보다 1 큰 수를 unsigned int로 표현가능하다는 보장이 표준에 없습니다" 라는 부분이 꺼림찍하네요 ㅋㅋ 왜 안될수 도 있는거지

고맙습니다!!!!!!!^^

clapmin의 이미지

사실 1번 문제가 회사 면접에서 나왓던 이야기 인데(어디인지는 말씀드리기가 곤란 ㅎ;;) 말씀해주신 분이 경력 10년 정도 되는 현직자 셨는데, 취업이 되서 나중에 왜 그렇게 말하셨는지 물어볼 기회가 있으면 좋겠네요 ㅎㅎ

2번 문제는 설명을 잘해주셔서 한번에 이해 했습니다!!
하지만 "int가 표현가능한 수의 최대값인 INT_MAX보다 1 큰 수를 unsigned int로 표현가능하다는 보장이 표준에 없습니다" 라는 부분이 꺼림찍하네요 ㅋㅋ 왜 안될수 도 있는거지

고맙습니다!!!!!!!^^

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.