Вы можете попытаться сделать неприятный хак, но здесь есть проблема с порядком байтов.Что бы вы ни делали для конвертации, откуда компилятор должен знать, что вы хотите, чтобы floor
была самой значительной частью результата, а fraction
- менее значимой частью?Любое решение, основанное на переинтерпретации памяти, будет работать для одного порядка байтов, но не для другого.
Вы должны либо:
(1) определить преобразование явно.Предполагая, что short
равно 16 битам:
unsigned int val = (x.floor << 16) + x.fraction;
(2) измените Fixed
так, чтобы вместо двух шортов он имел элемент int
, а затем при необходимости разложил вместо составление при необходимости.
Если вы хотите, чтобы сложение было быстрым, то (2) это то, что нужно сделать.Если у вас 64-битный тип, то вы также можете выполнять умножение без декомпозиции: unsigned int result = (((uint64_t)x) * y) >> 16
.
Между прочим, неприятный хак будет:
unsigned int val;
assert(sizeof(Fixed) == sizeof(unsigned int)) // could be a static test
assert(2 * sizeof(unsigned short) == sizeof(unsigned int)) // could be a static test
memcpy(&val, &x, sizeof(unsigned int));
Это будетработать в системе с прямым порядком байтов, где Fixed не имеет заполнения (а целочисленные типы не имеют битов заполнения).В системе с прямым порядком байтов вам нужно, чтобы члены Fixed находились в другом порядке, поэтому это неприятно.Иногда приведение к использованию через memcpy - это правильная вещь (в этом случае это скорее «трюк», чем «противный хак»).Это просто не тот случай.