Необходимо выполнить 64-битное умножение на машине с 32-битной длиной - PullRequest
2 голосов
/ 29 мая 2011

Я работаю над небольшой встроенной системой с 32-битными целыми числами.Для одного расчета мне нужно вывести время с 1970 года в мс.Я могу получить время в 32-битных беззнаковых длинных секундах с 1970 года, но как я могу представить это как 64-битное нет.мс, если мой самый большой int только 32бит?Я уверен, что у stackoverflow будет хитрый ответ!Я использую Dynamic C, близкий к стандартному C. У меня есть пример кода из другой системы, имеющей тип данных длиной 64 бита:

long long T = (long long)(SampleTime * 1000.0 + 0.5);
data.TimeLower = (unsigned int)(T & 0xffffffff);
data.TimeUpper = (unsigned short)((T >> 32) & 0xffff);

Ответы [ 3 ]

1 голос
/ 29 мая 2011

Поскольку вы умножаете только на 1000 (секунд -> миллис), вы можете сделать это с помощью двух 16-битных умножителей и одного сложения и небольшого изменения, я использовал ваш предполагаемый тип данных для сохранения результата ниже:

uint32_t time32 = time();
uint32_t t1 = (time32 & 0xffff) * 1000;
uint32_t t2 = ((time32 >> 16) * 1000) + (t1 >> 16);
data.TimeLower = (uint32_t) ((t2 & 0xffff) << 16) | (t1 & 0xffff);
data.TimeUpper = (uint32_t) (t2 >> 16);
0 голосов
/ 29 мая 2011

Было бы полезно, если бы вы более конкретно указали, какие виды вычислений вам нужно сделать. 64-битное умножение, реализованное с 32-битными операциями, довольно медленное, и у вас могут быть дополнительные издержки 64-битного деления (для преобразования в секунды и миллисекунды), что еще медленнее.

Не зная больше о том, что именно вам нужно делать, мне кажется, что было бы более эффективно использовать структуру, содержащую 32-разрядное целое число без знака для числа секунд и 16-разрядное целое число для числа миллисекунд («остаток»). (Или используйте 32-битное int для миллисекунд, если 64-битное выравнивание важнее, чем сохранение пары байтов.)

0 голосов
/ 29 мая 2011

Стандартный подход, предполагающий наличие умножения 16x16-> 32, состоит в том, чтобы разделить оба числа на 16-битную старшую и младшую части, вычислить четыре частичных произведения и добавить результаты.Если у вас нет примитива 16x16-> 32, который быстрее, чем примитив 32x32-> 32, я не уверен, какой будет наилучший подход.Я думаю, что умножение 32x32-> 32 должно быть более полезным, чем умножение на 16x16-> 32, но я не могу думать, как его использовать.

Лично я хотел бы, чтобы был стандартный примитив для возвратаверхняя половина умножения NxN (безусловно, 32x32, также 16x16 для небольших машин и 64x64 для больших).

...