리눅스에서 struct timeval 에 있는 sec와 usec를 double 에 넣는 방법.

이양반의 이미지

아무 고민없이 생각한 방법은
double time = (double)sec + (double)usec / 1000000;
였습니다.
결과는 나오겠지만
좀더 효율적인 방법이 없을까 해서요.

drinkme의 이미지

double time;
*(int*)&time = (int)sec;
*(((int*)&time)+1) = (int)usec;

ddoman의 이미지

저게 정말 돌아가나요?
double 과 int는 저장되는 구조가 다른데, double을 int 저장소로 이해하게끔 - *(int*)&time -
해놓고서 저장을 하면..

원하는대로 동작할것 같지가 않은데...

실제로 제 x86 gcc 4.x에서는 잘못된 결과를 출력하네요.
drinkme님이 올리신 코드가 어떻게 돌아가는지 궁금합니다.

drinkme의 이미지

님의 질문에
단순히 double형 변수에 sec와 msec를 손상없이 넣고 싶다고 하신것 아닌가요?
그래서, 손상없이 넣는 방법을 알려드린 겁니다. 반대로 하면, 저장한 값을 손상없이 꺼낼 수 있습니다.
double 값을 직접 읽어보시는 것은 의미가 없습니다. 이상한 값일테니까요.

double은 8바이트를 차지합니다.
그래서, 메모리상에서
상위 4바이트에 sec를. 하위 4바이트에 msec를 넣은 겁니다.

ddoman의 이미지

drinkme wrote:
님의 질문에
단순히 double형 변수에 sec와 msec를 손상없이 넣고 싶다고 하신것 아닌가요?
그래서, 손상없이 넣는 방법을 알려드린 겁니다. 반대로 하면, 저장한 값을 손상없이 꺼낼 수 있습니다.
double 값을 직접 읽어보시는 것은 의미가 없습니다. 이상한 값일테니까요.

"손상 없이"라는 표현이 질문에서 보이지는 않지만,
아마 drinkme님과 제가 이해한 질문의 요지가 달랐나봅니다.

질문의 어떤 곳에서도 단순히 double 변수를 저장 장소로만 이용하고, double로써는 쓸 수 없어도 괜찮으니,
어떻게 메모리 복사를 할수 있을까? 라는 식으로 이해할만한 요지는 없었다고 생각했는데,
drinkme님은 그렇게 받아들였나 보네요.

drinkme wrote:
double은 8바이트를 차지합니다.
그래서, 메모리상에서
상위 4바이트에 sec를. 하위 4바이트에 msec를 넣은 겁니다.

항상 맞는 말은 아닙니다.
timeval의 sec은 time_t msec는 suseconds_t 로 정의 되어있으며,

OpenGroup (X/Open)에는 time_t 가 다음과 같이 정의되어 있습니다.
time_t ... shall be integer or real-floating types.

또한 suseconds_t 의 정의는 다음과 같습니다.
The type suseconds_t shall be a signed integer type capable of storing values at least in the range [-1, 1000000]. [Option End]

The implementation ... in which the widths of ... suseconds_t, and useconds_t are no greater than the width of type long.

즉 최소한 20bit이상의 type long보다 같거나 작은 크기를 갖으면 됩니다.

drinkme의 이미지

네. 맞네요.
님의 질문을 잘 못 이해했습니다.
혼동드려 죄송합니다.

kukyakya의 이미지

double time = (1000000*sec + usec) / 1000000.;

실수연산 인스트럭션은 줄어들 것으로 예상합니다만 1000000*sec가 오버플로우될 수 있겠네요.
실수 연산이 느리다곤 해도 성능에 크게 영향을 미치지 않는다면 그대로 사용하시는게 좋지 않을까요?

Anti-Lock의 이미지

나름 좋은듯하네요

sec 가 0~59 아닌가요?
오버플로 없겠죠... (32비트라면)

doraq의 이미지

그 값의 단위가 초라는거지 시간중의 초부분만 들어가는게 아닙니다.
예) gettimeofday

그리고 저는 mili second 단위의 시간을 다음과 같이 만들어 씁니다.

U64 a_time_now_msec(void)
{
    U64 t;
    struct timeval tv;
    gettimeofday(&tv, NULL);
    t = ((U64)tv.tv_sec)*1000 + tv.tv_usec/1000;
    return t;
}
ddoman의 이미지

time_t에는 분, 시, 일, 달, 그리고 년의 개념이 없습니다.

그래서 기준점이 되는 1970년 1월 1일 0시 0초를 기준으로
매초를 세어가며 저장 하고 있는 저장소가 바로 time_t의 sec입니다.

즉 time_t sec의 value가 5000 이 었다면
그 시간은

5000 / 60(분) / 60(시간) => 1970년 1월 1일 1시23분 20초를 나타내는 값이죠

그래서 time_t의 정의를 32 bit signed integer로 해놓은 유닉스들이 많았기에
Year 2038 Problem이라는 문제가 있고요 ( http://en.wikipedia.org/wiki/Year_2038_problem ): 2^31 / 60(초) / 60(분) / 24(시) / 365(일) 로 나누면 68년이 나오고, 즉, 32bit signed integer로 sec을 정의하면, 1970으로부터 68년 후인, 2038년에 오버플로우가 생긴다는 Y2K스러운 문제입니다.

위키페이지의 해결책 부분을 보면 OS들이 Year 2038 Problem을 어떻게 해결하가고 있는지 알려줍니다. 재미삼아 한번 읽어보세요. :)

time_t에 대해 더 알고 싶고, 왜 1970년 1월 1일이고, 왜 날짜를 시간, 일, 월, 년 없이 그냥 1초 단위로 카운트를 하고 있는지
궁금하다면

Unix Time 의 위키 페이지 http://en.wikipedia.org/wiki/Unix_time
time_t 의 위키 페이지 http://en.wikipedia.org/wiki/Time_t

를 읽어보시면 답이 다 다옵니다.

Anti-Lock의 이미지

역시나 얼핏 계산식만 보고 글쓰는게 아니었는데....
식만 보니 sec과 usec 인줄로만...ㅋ
time_t 는 알았는데, timeval 은 잘 몰랐군요.
그래서 이녀석은 단위별로 시간을 제공하는줄 착각을 했습니다.

근데, 친절하시군요... 읽을거리를 주시다니~

댓글 달기

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