[완료] long long 형과 printf의 문제?

lebleu2u의 이미지

안녕하세요.
코드를 짜던중 다음과 같은 case가 발생해서 그 이유를 알고 싶어 게시합니다.

unsigned long long _u_long=10LLU;
printf("%llu\n", _u_long);
printf("%d\n", _u_long);

printf("%d %llu\n", _u_long,_u_long);
printf("%llu %d %llu %d \n", _u_long,_u_long,_u_long,_u_long);

결과

10
10 42949672960
10 10 42949672960 0

물론 위 예제는 printf에서 constant type에 맞추지 못했으므로 잘못된 코드입니다.
하지만 궁금한 것은 %d로 unsigned long long을 한번찍은후에 같은 printf문에서 %llu로 찍을때 쓰레기 값이 나오는것인데요. 이때 long long 타입이 어떻게 만들어 졌는지 궁금해서 물어보는 것입니다.

제 생각에는
1. unsigned long long이 sw적으로 lnt_H+lnt_L형태로 구현되었다.
2. 하지만 long long 타입을 printf문에서 %d로 호출하면 int형으로 cast되서 값을 보여준다.
3. 이때 바로 어떤 함수 end 상태여야 sw로 구현된 int_H+int_L의 long long 타입이 제자리를 찾는데
4. end되기도 전에 %llu로 다시 호출해 버리면 int형으로 cast된 상태에서 %llu를 찍으므로 int+int형으로 만들어진 long long이 int_H을 값을 찍어버리므로 int MAX값에 가까운것이 찍히고
5. 이후 다시 %d를 찍으면 3.번과 마찬가지고 cast된 비어바린 int_L에서 0값을 출력하게 된다.

아시는분은 조언좀 해주시면 감사하겠습니다.

익명사용자의 이미지

플랫폼마다 다 다른데요.
알 필요 없다는 얘기.

lebleu2u의 이미지

저도 관심 없으면 넘어가도 좋겠으나 요즘 cpu에서 int형이 32bit가 기본인 요즘 long long을 지원한다?라는 것은 64bit 형을 sw로 구현했다고 생각했고 위 상황을 생각해 보건데 int_H+int_L 인지? 즉, 어떻게 구현했는지 궁금했을 따름입니다.

최소 어디를 찾으면 나올것이다. 이런 답변을 기대했으나
윗글과 같은 답변을 보면 기분 참 묘하지요.

말하신것 처럼 알 필요가 없다는 것은 상대적인 것인데도 불구하고 그것이 곧 쓸모 없다.로 생각하신 다면 할말 없습니다.

IsExist의 이미지

printf 류의 함수에서 format specifier가 의미하는것 중에서 데이터 타입은 파라메터를 어떻게
해석을 할거냐 하는걸 말합니다. %d 는 signed int 로 해석을 하도록 약속을 합니다.
실제 파라메터는 포인터일 수도 있고 char, long, long long 일 수도 있습니다.

메모리상의 값을 어떤 타입으로 인식하고 해석합니다.

그럼 long long 타입을 printf 류 함수에서 제대로 해석하도록

%lld, %lli, %llo, %llu, %llx 등으로 지정해야 합니다.

printf ("%d %llu\n", u_long, u_long); 

위 코드에서 파라메터로 u_long이 두번 넘어갔기때문에 8바이트가 두번 전체 16바이트가 전달됩니다.
이제 %d에 의해 처음 4바이트를 해석하고 %llu 에서 이후 4바이트부터 12바이트까지
8바이트를 해석합니다. 남은 4바이트는 printf 호출에서 아무것도 안 하죠.

이제 platform에 따라 메모리상의 값을 실제 해석 하겠습니다.
값이 0x00 00 00 00 00 00 00 0A(Big Endian) 인 u_long, u_long 이 두번 넘어가기 때문에
32비트 x86에서는 0x0A 00 00 00 00 00 00 00 (Little Endian) 이게 두개 넘어 갑니다.
이제 printf에서 %d를 만나서 처음 4바이트 0x0A 00 00 00(Little Endian) 가 먼저 해석되고
%llu 에 의해 0x00 00 00 00 0x0A 00 00 00(Little Endian) 을 해석해서
0x00 00 00 0A 00 00 00 00 (Big Endian)값을 출력합니다.
남은 4바이트는 아무 해석도 안합니다. printf 입장에서는 4바이트가 남아 있는지 모릅니다.

---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

lebleu2u의 이미지

감사합니다.

즉, 컴파일러가 지원하는 long long형은 32+32로 구현된것이 맞군요.

IsExist의 이미지

정확히는 library 라고 해야 맞겠지요. printf 가 포함된 라이브러리 말입니다.
64비트용이냐, big endian 이냐에 따라 틀리구요.
---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

---------
간디가 말한 우리를 파괴시키는 7가지 요소

첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스

이익추구를 위해서라면..

다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치

익명사용자의 이미지

library라기보다는 컴파일러, 좀 더 정확히 말하면 ABI (application binary interface) 가 맞겠습니다.

여기서 문제가 되는 건 가변 인자의 함수를 호출할 때 인자가 스택에 어떻게 담기느냐 하는 것인데, 이건 라이브러리 단위로 결정되는 것이 아니라 OS와 CPU가 같으면 이 위에서 도는 모든 라이브러리가 같은 방식을 써야 합니다. 그렇지 않으면 A library에서 B library의 함수를 부를 때 인자가 제대로 넘어가는 걸 보장할 수가 없겠죠.

익명 사용자의 이미지

typedefine 으로 정의된 unsiged long long 형을 반환하는 함수를 개인적으로 사용중인데,

printf ("%llu %llu", myfunc(), myfunc);

의 결과가 [0 820647991372384] 과 같이 출력되어 고민 중 이 글을 통해 해결하였습니다.
아래처럼 타입을 재정의하면 해결되더군요..
printf ("%llu %llu", (myull)myfunc(), (myull)myfunc);

이 글이 큰 도움이 되었습니다. 감사합니다.

shint의 이미지

int64_t 사용하는 방법입니다. 결과값은 좀 다릅니다. C 에서만 컴파일 됩니다.
http://codepad.org/ZsTg6rWI
http://codepad.org/br4WwF1f

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.