首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C: struct timespec c库

C: struct timespec c库
EN

Code Review用户
提问于 2020-11-27 17:07:04
回答 1查看 808关注 0票数 3

我正在尝试编写一个较小的库,使我能够度量使用struct timespec时测量的平均时间。因为C不允许操作符重载,所以我不得不构建函数。我知道像end_time < start_time这样的检查是没有完成的,但是为了实现代码中的某种短处,我忽略了它们。计算的准确性是首要目标。

代码语言:javascript
复制
enum { NS_PER_SECOND = 1000000000L };
enum { MAX_NS = 999999999 };

// t1 --> start time
// t2 --> end time
// set t1 and t2 by:
//        clock_gettime(CLOCK_REALTIME, &t1);
struct timespec get_timespec_diff(const struct timespec t1, const struct timespec t2)
{
    struct timespec t;

    t.tv_nsec = t2.tv_nsec - t1.tv_nsec;
    t.tv_sec  = t2.tv_sec - t1.tv_sec;

    if (t.tv_sec > 0 && t.tv_nsec < 0) {
        t.tv_nsec += NS_PER_SECOND;
        t.tv_sec--;
    } else if (t.tv_sec < 0 && t.tv_nsec > 0) {
        t.tv_nsec -= NS_PER_SECOND;
        t.tv_sec++;
    }

    return t;
}

struct timespec timespec_add(const struct timespec t1, const struct timespec t2) {

    unsigned int total_ns   = t1.tv_nsec + t2.tv_nsec;
    unsigned int total_s    = t1.tv_sec  + t2.tv_sec;

    while(total_ns > MAX_NS) {
        total_ns -= (unsigned)(MAX_NS + 1);
        total_s++;
    }

    struct timespec ret;
    ret.tv_sec  = total_s;
    ret.tv_nsec = total_ns;

    return ret;
}

struct timespec timespec_avg(const struct timespec t, const unsigned n) {

    struct timespec ret;
    ret.tv_sec  = 0;
    ret.tv_nsec = 0;

    unsigned int total_ns = t.tv_nsec + (t.tv_sec * (MAX_NS+1));
    unsigned int avg_ns = total_ns/n;

    while(avg_ns > MAX_NS) {
        ret.tv_sec++;
        avg_ns /= 10;
    }
    ret.tv_nsec = avg_ns;

    return ret;
}
EN

回答 1

Code Review用户

发布于 2020-11-29 16:00:14

time_t假设,而不是规范

OP的代码假设1) time_t是整数类型。可能是浮点。2) unsigned/int不是16位--它们可能是。

法线范围

正常范围为.tv_sec >= 00 <= .tv_nsec <= 999999999。有用的是,代码不太依赖于这一点。

溢出风险

timespec_add()中,t1.tv_sec + t2.tv_sec可能导致溢出,从而导致未定义的行为。

unsigned int total_ns = t1.tv_nsec + t2.tv_nsec;是16位时,unsigned很容易无法提供正确的结果--最好使用long.

奇名

timespec_avg(const struct timespec t, const unsigned n)看起来更像是一个鸿沟,而不是平均时间。

备选建议:

代码语言:javascript
复制
#include <time.h>
#define NS_PER_SECOND 1000000000

// Averaging without overflow, even if `t1,t2` outside normal range
struct timespec timespec_avg(struct timespec t1, struct timespec t2) {
  struct timespec avg;
  int remainder = t1.tv_sec % 2 + t2.tv_sec % 2;
  avg.tv_sec = t1.tv_sec / 2 + t1.tv_sec / 2;
  avg.tv_nsec = t1.tv_nsec / 2 + t1.tv_nsec / 2 + (t1.tv_nsec % 2 + t1.tv_nsec % 2) / 2;
  avg.tv_sec += avg.tv_nsec / NS_PER_SECOND;
  avg.tv_nsec = avg.tv_nsec % NS_PER_SECOND + (NS_PER_SECOND / 2 * remainder);
  if (avg.tv_nsec >= NS_PER_SECOND) {
    avg.tv_nsec -= NS_PER_SECOND;
    avg.tv_sec++;
  } else if (avg.tv_nsec < 0) {
    avg.tv_nsec += NS_PER_SECOND;
    avg.tv_sec--;
  }
  return avg;
}
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/252762

复制
相关文章

相似问题

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