roboforum.ru

Технический форум по робототехнике.

64 бит - 8 байтовая арифметика в AVR. Как ?

64 бит - 8 байтовая арифметика в AVR. Как ?

Atmega16 » 26 июн 2007, 14:03

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

-= Александр =- » 26 июн 2007, 15:58

Как вариант - вручную. Тоесть 2 переменные, старшая и младшая.  :wink:

avr123.nm.ru » 26 июн 2007, 23:50

Там наверняка кто-то делал.

http://telesys.ru/wwwboards/mcontrol/index.shtml

Atmega16 » 27 июн 2007, 18:19

придется мне долго думать.я там не разгребу.а можно поподробней про по частям?как можно сделать умножение отдельно мл и ст части?

avr123.nm.ru » 27 июн 2007, 19:55

Помню видел гдето в сети библиотеку для чисел до 24 бит.  Пошукай через GOOGLE.com

avr123.nm.ru » 27 июн 2007, 20:10

Вот нашел кое что, наверно можно на Си переложить.

http://www.6502.org/source/

http://www.6502.org/source/integers/32muldiv.htm

avr123.nm.ru » 27 июн 2007, 20:31

В апноуте есть схемы умножения по половинками 16 на 16  

возможно она применима и для 32 на 32

http://www.atmel.com/dyn/resources/prod ... oc1631.pdf

AVR201 Using the AVR Hardware Multiplier

avr123.nm.ru » 27 июн 2007, 20:36

Вот кейл пример 16 на 16  и тоже как отправная точка

http://www.keil.com/support/docs/2008.htm

avr123.nm.ru » 27 июн 2007, 21:33

32 бит умножить на 32 бит (все единицы) будет  FF FF FF FE 00 00 00 01

FFFFFFFE00000001  в десятичном виде - 18446744065119617025


18 446 744 065 119 617 025


т.е. вы можете привести ваше 32 битное число к типу float  или double

float 32 ±1.175e-38 to ±3.402e38
double 32 ±1.175e-38 to ±3.402e38

вот так

(float)число

Сделать умножение и результат привести к двум 32 битным числам нужного вам типа

long int                32 -2147483648 to 2147483647
unsigned long int 32 0 to 4294967295
signed long int 32 -2147483648 to 2147483647

Это приведение будет "хитрым"

Старшее 32 битное число - будет результат поделить на 2 в степени 32

А младшее 32 битное наверно будет - результат минус (старшее число умноженое на 2 с теп 32).


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

==============

Пример

если  18446744065119617025  поделить на 2 в 32 степени (4294967296) получим   4294967294,0000000002328306436539


FFFFFFFE   и  остаток    0,0000000002328306436539

это старшее 32 битное число в нужном нам 64 битном.


теперь вычтем  из 18446744065119617025  число 4294967294 умноженое на 2 в степени 32 (4294967296)  получаем число  1
это младшее 32 битное число.


так мы получили  64 битный результат:    FF FF FF FE 00 00 00 01
Последний раз редактировалось avr123.nm.ru 27 июн 2007, 22:26, всего редактировалось 1 раз.

avr123.nm.ru » 27 июн 2007, 21:38


Atmega16 » 28 июн 2007, 10:07

спасибо!буду разбираться.

avr123.nm.ru » 28 июн 2007, 13:00

Я считал в калькуляторе Windows в инженерном режиме.

hexelon.com  - мощный бесплатный калькулятор.

Vooon » 28 июн 2007, 14:06

avr123.nm.ru писал(а):hexelon.com  - мощный бесплатный калькулятор.

мне этот больше нравится: http://www.rionnag.com/rionacalc.php
жаль в вине не завелся

кстати этот hexelon в вине запустился, но считать отказывается.
потом врядли он вычислит 1024! :)

avr123.nm.ru » 28 июн 2007, 14:37

Вот на телесистемах подсказали вариант умножения:

http://telesys.ru/wwwboards/mcontrol/17 ... 3501.shtml


--------------------------------------------------------------------------------


На примере беззнаковых
result=(low1+2^16*high1)(low2+2^16*high2)=
low1*low2+2^16*(low1*high2+low2*high1)+2^32*high1*high2.

Сомножители: unsigned long operand1,operand2;

unsigned long low_result; //low 32 bits of result
unsigned long high_result; //high 32 bits of result;
unsigned long tmp;
unsigned long lop1,lop2;

lop1=operand1&0xffffL;
lop2=operand2&0xffffL;

operand1>>=16;
operand2>>=16;

low_result=lop1*lop2;
tmp=low_result>>16;
high_result=operand1*operand2;

operand1*=lop2;
operand2*=lop1;
lop1=operand1&0xffffL;
operand1>>=16;
lop2=operand2&0xffffL;
operand2>>=16;

tmp+=lop1+lop2;
lop1=tmp<<16;
low_result+=lop1;

tmp>>=16;
high_result+=(tmp+operand1+operand2);

====

Я не разбирался.  :lol:

Atmega16 » 01 июл 2007, 17:05

спасибо всем за помощь!попробую прилепить этот код к авр.


Rambler\'s Top100 Mail.ru counter