Как преобразовать 64-битный длинный тип данных в 16-битный тип данных

Я хотел бы знать, как преобразовать 64 bit long тип данных в любой из 16 bit типов данных. Эта функция требуется в приложении Ethernet для включения отметки времени. Только 2 байта ( 16 бит ) доступны для включения отметки времени. Но мы получаем 64 bit long в качестве значения метки времени из Win API. Таким образом, преобразование из 64-битного типа данных в 16-битный тип данных необходимо.


person Mahesh    schedule 28.01.2009    source источник


Ответы (4)


Ну, вы не можете поместить 64 бита информации в 16 бит памяти без потери части информации.

Так что вам решать, как квантизировать или обрезать временную метку. Например. предположим, вы получаете отметку времени с точностью до наносекунды, но вам нужно сохранить ее только с точностью до секунд. В этом случае вы делите 64-битное число на 1000000000 и остаетесь с секундами. Тогда он может уместиться в 16 бит или нет (16 бит будут хранить только до 65535 секунд).

Если он не подходит, то у вас будет периодическая отметка времени. Что, опять же, может быть проблемой в вашем случае, а может и не быть проблемой.

В любом случае, если вам нужно взаимодействовать с существующей библиотекой, для которой требуются метки времени, выясните, что ей нужно в этой метке времени (такты часов? секунды? годы?). Затем выясните, что возвращает функция времени Windows, которую вы используете. Затем преобразуйте единицу времени Windows в единицу времени библиотеки, которую вы используете.

person NeARAZ    schedule 28.01.2009

16 бит может быть или не хватить, в зависимости от того, для чего вам нужна метка времени. Для большинства целей он слишком мал или, по крайней мере, неудобен. Но некоторые примеры, где это может работать, могут быть: тайм-ауты, измерение времени приема-передачи для пакетов, грубое измерение временных интервалов (что может хорошо работать для отображения информации о времени для пользователей) и так далее.

С другой стороны, это, вероятно, бесполезно для переупорядочивания пакетов. Если это так, я бы посоветовал вам заменить метку времени счетчиком последовательности. В зависимости от типичного количества пакетов в потоке вы можете даже сократить несколько битов и использовать их для других целей, поскольку счетчики последовательности могут легче обрабатывать перенос.

person Eduard - Gabriel Munteanu    schedule 28.01.2009

Как говорили другие, первая проблема заключается в выборе правильного масштабирования. Вы должны сбалансировать свое разрешение с желаемым максимальным диапазоном. Один из способов подумать об этом — решить, сколько секунд на бит вы хотите. С помощью 1 секунды на бит вы можете выразить значения от 1 секунды до 65536 секунд или ~1000 минут. 1 миллисекунда на бит позволяет увеличить время от 0,001 секунды до 65,5 секунды.

Вот один из способов преобразования.

#define seconds_per_bit   .0001  <--YOUR VALUE HERE.
#define bits_per_second   (1/seconds_per_bit);  
int16 timestamp()
{
  Int64 counts_per_second,counts;

  QueryPerformanceFrequency(&counts_per_sec);
  QueryPerformanceCounter(&counts);  
  return (UInt16)(counts * bits_per_second / counts_per_second);
}
person AShelly    schedule 28.01.2009

Это полностью зависит от того, для чего вы используете метку времени. Вы упомянули ethernet, поэтому одно очевидное использование, которое я мог бы представить, — это заказ пакетов. И в этом случае все, что вам действительно нужно, это счетчик. Вместо вашей метки времени, говорящей «этот пакет был отправлен 14 мая в 14:35», вы можете просто сказать «это 4023-й пакет».

Если вам нужно, чтобы он записывал фактическое время, вам просто нужно выбрать, какие его части актуальны. 16 бит дают вам 65536 значений для игры. Вы хотите, чтобы они представляли секунды? Тогда ваши метки времени будут меняться каждые 18 часов.

Или они могут быть минутами. Тогда пройдет 45 дней, прежде чем они обернутся. Или дни, или микросекунды, все зависит от того, что вам нужно.

Но единственный способ преобразовать 64-битное значение в 16-битное — удалить 48 бит данных. Вы выбираете, какие

person jalf    schedule 28.01.2009