首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >timeval_subtract解释

timeval_subtract解释
EN

Stack Overflow用户
提问于 2013-04-06 03:39:28
回答 1查看 10.7K关注 0票数 4

使用"timeval_subtract“函数来查找两种结构时间类型之间的时间,有人能解释一下用于”通过更新y来执行后面减法的进位“和其他部分的目的和逐步数学吗?我理解这个函数的目的以及如何在一个程序中实现它,但我想了解它是如何在程序内部工作的,在任何地方都找不到任何解释,而且我似乎无法理解它。

代码语言:javascript
复制
int timeval_subtract (struct timeval *result, struct timeval *x,struct timeval  *y)  
{  
  /* Perform the carry for the later subtraction by updating y. */  
  if (x->tv_usec < y->tv_usec) {  
    int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;  
    y->tv_usec -= 1000000 * nsec;  
    y->tv_sec += nsec;  
  }  
  if (x->tv_usec - y->tv_usec > 1000000) {  
    int nsec = (y->tv_usec - x->tv_usec) / 1000000;  
    y->tv_usec += 1000000 * nsec;  
    y->tv_sec -= nsec;  
  }  
  
  /* Compute the time remaining to wait.
     tv_usec is certainly positive. */  
  result->tv_sec = x->tv_sec - y->tv_sec;  
  result->tv_usec = x->tv_usec - y->tv_usec;  
  
  /* Return 1 if result is negative. */  
  return x->tv_sec < y->tv_sec;  
}

它是一个与GNU库相关的函数,用于确定经过的时间节点/运行-Time.html,因此我并不是在寻找改进,而是简单地解释为什么在其中进行除法、加减、减法和乘法。这些特定的算术操作实现了什么?/为什么它们被完成/没有完成?我已经完成了这一步,但仍然无法理解它。我会继续这样做,直到我这样做(甚至在有人向我解释之后),但我希望从已经理解它的人那里获得一些洞察力。这个平台是UNIX,这是我刚开始使用的,但我认为它不会改变函数内部正在进行的操作。与所使用的算法相比,它更多地是一个关于正在执行的算法的问题。

EN

回答 1

Stack Overflow用户

发布于 2022-07-27 17:26:16

下面是一个timeval_subtract():

  • 注释了为什么和如何携带usec <->秒
  • 使用const输入结构(复制y到subtrahend sh)
  • 使输出微秒正常化(0-999999)

回想一下,tv_usec是自tv_sec以来经过的微秒。

所以diff{-1,2000001} == diff{1,1}是真的,tv{0,-1} == tv{-1,999999}也是。

代码语言:javascript
复制
/*  copied from
    https://www.gnu.org/software/libc/manual/html_node/Calculating-Elapsed-Time.html
    Changed input timevals to const, added // comments.
    Changed condition of 2nd if.
*/
int
timeval_subtract (const struct timeval *x, const struct timeval *y, struct timeval *diff)
{
    //subtraction found the difference, the minuend minus the subtrahend
    timeval sh = *y;    // mutable local copy of y, sh (the subtrahend)
    /* Perform the carry for the later subtraction by updating sh. */
    if (x->tv_usec < sh.tv_usec) {
        // reduce sh.usecs so usec diff will be positive.
        // carry or lend sh.usecs to sh.secs, in packages of 1e6 usecs (whole secs).
        // as we are here, we know we must carry at least 1 sec (1 million usec)
        int nsec = (sh.tv_usec - x->tv_usec) / 1000000 + 1;
        sh.tv_usec -= 1000000 * nsec;
        sh.tv_sec += nsec;
    }
    // if (x->tv_usec - sh.tv_usec > 1000000) {  // could show tv{x,1000000}, not 'normal'
    if (x->tv_usec - sh.tv_usec > 999999) {      // normalize 0-999999
        // normalize diff; increase sh.usecs so usec diff will be < 1000000.
        // carry or lend whole sh.secs to sh.usecs
        int nsec = (x->tv_usec - sh.tv_usec) / 1000000;
        sh.tv_usec += 1000000 * nsec;
        sh.tv_sec -= nsec;
    }
    // should now have the subtrahend sec/usec that will produce normalized difference
    /*  Compute the time remaining to wait.
        tv_usec is certainly positive. */
    diff->tv_sec = x->tv_sec - sh.tv_sec;
    diff->tv_usec = x->tv_usec - sh.tv_usec;

    /* Return 1 if diff is negative. */
    return x->tv_sec < sh.tv_sec;
    // timeval_subtract
}

如果您需要同时支持32位和64位time_t类型,那么输出结果就会变得复杂,但是您可以使用如下所示调用timeval_subtract():

代码语言:javascript
复制
    // replace MY_SPECIFIC_PREPROC_8B_DEF with your own 
    //  preprocessor time_t distinguishing define
    #if defined MY_SPECIFIC_PREPROC_8B_DEF
     #define LSPEC "lld"                     // format specifier input length
     char fmt[] = "% 020" LSPEC " % 011ld "; // long long tv_sec"
     #define MAX_TIME_T 0x7fffffffffffffff
     #define MIN_TIME_T 0x8000000000000000
    #else
     #define LSPEC "ld"
     char fmt[] = "% 011" LSPEC " % 011ld "; // less chars for long tv_sec"
     #define MAX_TIME_T 0x7fffffff
     #define MIN_TIME_T 0x80000000
    #endif

    const time_t max_time_t = MAX_TIME_T;
    const time_t min_time_t = MIN_TIME_T;

    // Test overflow of both timeval members, sec & usec
    struct timeval a = {min_time_t, 1};   // 1 usec > negative overflow
    struct timeval b = {0, 0};            // our subtrahend, ++1 usec in loop
    struct timeval c = {0, 0};      // holds result; difference in this case

    strcat (fmt, "= a{%" LSPEC ",%ld} - b{%" LSPEC ",%ld}\n");

    for (auto i=0; i<3; i++) {
        timeval_subtract (&a,&b,&c);
        Serial.printf(fmt,
          c.tv_sec, c.tv_usec, a.tv_sec, a.tv_usec, b.tv_sec, b.tv_usec);
        b.tv_usec += 1;                 // normal time flow
    }

// Without an appropriate preprocessor define this may compile

    for (auto i=0; i<3; i++) {
        timeval_subtract (&a,&b,&c);
        // explicit casts try to quiet compiler on other sized type_t systems
        if (8 == sizeof(time_t)) {
            Serial.printf("% 020lld % 011ld = a{%lld,%ld} - b{%lld,%ld}\n",
                (long long)c.tv_sec, c.tv_usec,
                (long long)a.tv_sec, a.tv_usec,
                (long long)b.tv_sec, b.tv_usec);
        }
        else if (4 == sizeof(time_t)) {
            Serial.printf("% 011ld % 011ld = a{%ld,%ld} - b{%ld,%ld}\n",
                (long)c.tv_sec, c.tv_usec,
                (long)a.tv_sec, a.tv_usec,
                (long)b.tv_sec, b.tv_usec);
        }
        b.tv_usec += 1;                 // normal time flow
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15846762

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档