Умножение 23-битных типов данных в системе без длинных - PullRequest
0 голосов
/ 03 марта 2009

Я пытаюсь реализовать операции с плавающей запятой в микроконтроллере, и пока у меня достаточно успеха.

Проблема заключается в способе умножения на моем компьютере, и он отлично работает:

unsigned long long gig,mm1,mm2;
unsigned long m,m1,m2;
mm1 = f1.float_parts.mantissa;
mm2 = f2.float_parts.mantissa;

m1 = f1.float_parts.mantissa;
m2 = f2.float_parts.mantissa;



gig = mm1*mm2; //this works fine I get all the bits I need since they are all long long, but won't work in the mcu

gig = m1*m2//this does not work, to be precise it gives only the 32 least significant bits , but works on the mcu

Итак, вы можете видеть, что моя проблема в том, что микроконтроллер сгенерирует неопределенный рефенс в __muldi3, если я попробую gig = mm1*mm2.

И если я попробую с меньшими типами данных, он сохранит только младшие биты, чего я не хочу. Мне нужны 23 битные биты продукта.

У кого-нибудь есть идеи относительно того, как я могу это сделать?

Ответы [ 3 ]

1 голос
/ 01 мая 2009

Комментарии в реализации FreeBSD для __muldi3 () имеют хорошее объяснение необходимой процедуры, см. muldi3.c . Если вы хотите перейти непосредственно к источнику (всегда хорошая идея!), Согласно комментариям, этот код был основан на алгоритме, описанном в книге Кнута Искусство компьютерного программирования том. 2 (2-е изд), раздел 4.3.3, с. 278. (Примечание: ссылка на 3-е издание.)

1 голос
/ 03 марта 2009

Извиняюсь за краткий ответ, я надеюсь, что кто-то еще найдет время, чтобы написать более полное объяснение, но в основном вы делаете точно так же, как когда вы умножаете два больших числа вручную на бумаге! Просто вместо того, чтобы работать с базой 10, вы работаете с базой 256. То есть обрабатываете свои числа как байтовые векторы и делаете с каждым байтом то, что вы делаете с цифрой, когда вы «умножаете руку».

0 голосов
/ 03 марта 2009

Возвращаясь к Intel 8088 (исходному ЦП ПК и последнему ЦП, для которого я написал код сборки), когда вы умножили два 16-битных числа (32 бита?), ЦПУ вернет 2 16-битных числа в двух разных регистрах - один с 16 msb и один с lsb.

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

В противном случае вам придется самостоятельно выполнять умножение.

...