Преобразовать краткий формат NTP в секунды

Я пытаюсь преобразовать Краткий формат RFC 5905 NTP в секунды. Краткий формат NTP представляет собой uint32_t, где первые 16 бит представляют собой секунды (т. е. секунды = формат >> 16), а остальные 16 бит — доли секунды (т. е. дробь = формат и 0xFFFF). После преобразования я бы хотел, чтобы результат был двойным.


person rn42v1r    schedule 16.01.2020    source источник
comment
Обязательно учитывайте порядок следования байтов. Формат NTP имеет обратный порядок байтов, в то время как многие машины (особенно процессоры x86 и x64) имеют обратный порядок байтов.   -  person Fred Larson    schedule 16.01.2020
comment
@FredLarson Спасибо, об этом уже позаботились :)   -  person rn42v1r    schedule 16.01.2020


Ответы (2)


Этот ответ взят из чата группы Google. Надеюсь, это поможет:
Рассматривайте это как 32-битную дробь с двоичной точкой слева, умножьте на миллион, оставьте целую часть.

microsecs = ((unsigned long long) frac * 1000000) >> 32;

Округлить (можно округлить до 1000000),

microsecs = ((unsigned long long) frac * 1000000 + (1LL<<31)) >> 32;
person Ugnes    schedule 16.01.2020
comment
Что вы имеете в виду под бинарной точкой слева? Сама дробь представляет собой uint16_t. Значит, frac — это просто дробь как uint32_t? - person rn42v1r; 16.01.2020

Поскольку TS_short является кратким форматом uint32_t RFC 5905 NTP, следующее преобразует его в секунды как двойное:

double secs = (double)(TS_short >> 16) + (double)(TS_short & 0xFFFF) / (double)(1LL << 16);
person rn42v1r    schedule 04.02.2020