有时64位操作失败

时间:2017-11-19 12:46:46

标签: c time-t

这是我第一次使用64位time_t结构来执行时间操作。编译器是TI针对CC3220SF的C编译器。

这里我的函数应该将秒返回到下一个事件:

#define ACQ_INTERVAL    1 // in minutes
time_t _lastAcquisition;

time_t _timeToAcquire(void)
{
    time_t now = _getEpoch(); // from internal RTC
    if (_lastAcquisition == 0) _lastAcquisition = now;
    time_t diff = now - _lastAcquisition; // seconds since last acquisition
    time_t next = ACQ_INTERVAL * 60;

    UART_PRINT("Interval is %lld s\r\n", next);
    UART_PRINT("Current epoch is %lld, last acquisition was %lld, next one in %lld s\r\n", now, _lastAcquisition, next - diff);
    return next - diff; // seconds to next acquisition
}

UART_PRINT只是printf的包装器。 这里是_getEpoch()函数:

time_t _getEpoch(void)
{
    _i16 ret;
    _u8 pConfigOpt = SL_DEVICE_GENERAL_DATE_TIME;
    _u16 pConfigLen = sizeof(SlDateTime_t);

    SlDateTime_t dateTime = {0};
    ret = sl_DeviceGet(SL_DEVICE_GENERAL, &pConfigOpt, &pConfigLen, (unsigned char *) &dateTime);
    ASSERT_ON_ERROR(ret);

    struct tm t;
    time_t t_of_day;

    t.tm_year = dateTime.tm_year - 1900;
    t.tm_mon = dateTime.tm_mon - 1;
    t.tm_mday = dateTime.tm_day;
    t.tm_hour = dateTime.tm_hour;
    t.tm_min = dateTime.tm_min;
    t.tm_sec = dateTime.tm_sec;
    t.tm_isdst = -1;
    t_of_day = mktime(&t);

    return t_of_day;
}

通常它工作正常,但有时我得到一些像这个输出的奇怪的东西:

  

间隔时间为60秒

     

当前时期为1511088032,上次收购为1511086500,下一次为18446744073709550144 s

显然有些不对劲。差异应该是1532。 此外,巨大的数字似乎像2 ^ 64 - x。但是x将是1742 ......我不明白它可能来自哪里。

我仔细检查了time_t的定义:

typedef long long __time64_t;

#if defined(_TARGET_DEFAULTS_TO_TIME64) || (__TI_TIME_USES_64) && __TI_TIME_USES_64)
    typedef __time64_t time_t;
#else
    typedef __time32_t time_t;
#endif

__TI_TIME_USES_64已定义并设置为1(IDE显示#if的第一部分是已启用的部分。

1 个答案:

答案 0 :(得分:1)

你有

now = 1511088032
_lastAcquisition = 1511086500
diff = now - _lastAcquisition = 1532
next - diff = 60 - diff = -1472

看起来你的平台上的%lld说明符看起来很错误并且像%llu(unsigned long long)一样工作。你看到的数字很大

18,446,744,073,709,550,144 = 2^64 - 1472

正好是-1472转换为无符号的64位值。如果long long有64位,则%lld说明符不应该产生大于INT64_MAX的数字,即9,223,372,036,854,775,807。