Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: перемножение вещественных чисел
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > MCS51
showone
подскажите пожалуйста
как перемножить два числа 3,25 на 0,75 ?
использую C8051F121 там есть аппаратный перемножитель.
все замечательно умножается если 0,2*0,007 или целое на целое, 1234*9874.
легко и быстро.
а как вот если число содержит и целую и дробную часть ?
т.е. 3,24*7,2 или 0,27*7,15

принимаются любые предложения.
заранее спасибо.
Stanislav
Цитата(showone @ Jan 19 2007, 16:02) *
подскажите пожалуйста
как перемножить два числа 3,25 на 0,75 ?
использую C8051F121 там есть аппаратный перемножитель.
все замечательно умножается если 0,2*0,007 или целое на целое, 1234*9874.
легко и быстро.
а как вот если число содержит и целую и дробную часть ?
т.е. 3,24*7,2 или 0,27*7,15

принимаются любые предложения.
заранее спасибо.
Это называется арифметикой с фиксированной точкой. Например, число 3,25 можно представить в виде 011.01000 (В) (взята разрядность операндов в 8 бит). Точка здесь отделяет целую часть от дробной, поставлена условно и должна держаться "в голове". Например, это же число можно записать и в виде 0011.0100. Первый формат называется 3.5, второй - 4.4. Число 0,75 в формате 4.4 будет выглядеть так: 0000.1100. После перемножения двух этих чисел формата 4.4 получим 00000010.01110000 - число в формате 8.8. Если хотите привести его к формату операндов, нужно сдвинуть результат влево на 4 разряда, и округлить до байта.
showone
спасибо, буду пробовать.
mihask
Цитата(showone @ Jan 22 2007, 13:28) *
спасибо, буду пробовать.


А почему не хотите воспользоваться библиотекой с плавающей точкой ? smile.gif
showone
подскажите еще пожалуйста.
вот есть mul ab с ним все понятно.
а если нужно умножить 388*435 т.е. числа которые больше байта ?
т.е. умножить два байта на два или на три байта ?
заранее спасибо.


Цитата(mihask @ Jan 22 2007, 10:58) *
Цитата(showone @ Jan 22 2007, 13:28) *

спасибо, буду пробовать.


А почему не хотите воспользоваться библиотекой с плавающей точкой ? smile.gif



пишу на ASM.
а где можно посмотреть эту библиотечку ? или примеры любые ?
mihask
Цитата(showone @ Jan 22 2007, 14:33) *
подскажите еще пожалуйста.
вот есть mul ab с ним все понятно.
а если нужно умножить 388*435 т.е. числа которые больше байта ?
т.е. умножить два байта на два или на три байта ?
заранее спасибо.


Цитата(mihask @ Jan 22 2007, 10:58) *

Цитата(showone @ Jan 22 2007, 13:28) *

спасибо, буду пробовать.


А почему не хотите воспользоваться библиотекой с плавающей точкой ? smile.gif



пишу на ASM.
а где можно посмотреть эту библиотечку ? или примеры любые ?




Вот библиотека с умножения положительных чисел с фиксированной запятой
UMN2_2B - ПРОГРАММА УМНОЖЕНИЯ 2 БАЙТОВОГО ЧИСЛА НА 2 БАЙТОВОЕ.
UMN -ПРОГРАММА УМНОЖЕНИЯ 6 БАЙТОВОГО ЧИСЛА НА 2 БАЙТОВОЕ.
причем из UMN2_2B можно сделать умножение n-БАЙТОВОГО ЧИСЛА НА m-БАЙТОВОЕ.

Но всеже лучше помоему перейти на Си и воспользоваться стандартной библиотекой с плавающей
точкой Keil или IAR.

Библиотеку с плавающей точкой для asm сейчас поищу у себя, я помоему ее с gaw.ru брал -
там где информация по 51-м контроллерам.




;ПРОГРАММА УМНОЖЕНИЯ 2 БАЙТОВОГО ЧИСЛА НА 2 БАЙТОВОЕ.
;ВХОД R0- АДРЕС УМОЖАЕМОГО ,R1 - АДРЕС 2 УМНОЖАЕМОГО.
;R0 - АДРЕС ПРОИЗВЕДЕНИЯ.

UMN2_2B:
MOV A,@R0
MOV B,@R1
MUL AB
PUSH B
MOV R3,A
MOV A,@R0
INC R1
MOV B,@R1
MUL AB
MOV R2,B
POP B
ADD A,B
MOV R4,A
MOV A,R2
ADDC A,#0
MOV R5,A

INC R0
MOV A,@R0
DEC R1
MOV B,@R1
MUL AB
PUSH B
MOV R6,A ;--------
MOV A,@R0
INC R1
MOV B,@R1
MUL AB
MOV R2,B
POP B
ADD A,B
MOV R7,A ;--------
MOV A,R2
ADDC A,#0
PUSH A
DEC R0

PUSH A
MOV A,R3
MOV @R0,A
INC R0
POP A

MOV A,R6
ADD A,R4 ;1
MOV @R0,A
INC R0

MOV A,R7
ADDC A,R5
MOV @R0,A ;2
INC R0

POP A
ADDC A,#0
MOV @R0,A ;3

RET






;ПРОГРАММА УМНОЖЕНИЯ 6 БАЙТОВОГО ЧИСЛА НА 2 БАЙТОВОЕ.
;ВХОД R0- АДРЕС УМОЖАЕМОГО ,R1 - АДРЕС 2 УМНОЖАЕМОГО.
;R0 - АДРЕС ПРОИЗВЕДЕНИЯ.
UMN:
MOV A,R1
MOV R7,A
MOV A,@R1
MOV R2,A
INC R1
MOV A,@R1
JNZ UMN1
ADD A,R2
JZ UMN_NA0
CJNE A,#1,UMN1
RET
UMN1: MOV A,R7
MOV R1,A
MOV A,@R1
MOV DPL,A
INC R1
MOV A,@R1
MOV DPH,A
MOV R4,#0
UMN2: CLR C
MOV A,DPL
RLC A
MOV DPL,A
MOV A,DPH
RLC A
MOV DPH,A
JC UMN3
INC R4
SJMP UMN2
UMN3: MOV A,#16
CLR C
SUBB A,R4
DEC A
MOV B,A
MOV A,R0
MOV R7,A
MOV A,@R0
INC R0
MOV R1,A
MOV A,@R0
INC R0
MOV R2,A
MOV A,@R0
INC R0
MOV R3,A
MOV A,@R0
INC R0
MOV R4,A
MOV A,@R0
INC R0
MOV R5,A
MOV A,@R0
MOV R6,A
UMN6: CALL SDVIG
CLR C
MOV A,DPL
RLC A
MOV DPL,A
MOV A,DPH
RLC A
MOV DPH,A
JNC UMN7
CALL SUMMA
UMN7: DJNZ B,UMN6
MOV A,R7
MOV R0,A
RET
UMN_NA0: MOV R5,#6
MOV A,R0
MOV R7,A
CLR A
U_NA0: MOV @R0,A
INC R0
DJNZ R5,U_NA0
MOV A,R7
MOV R0,A
RET

SDVIG:
CLR C
SDV_NOC: MOV A,R7
MOV R0,A
MOV A,@R0
RLC A
MOV @R0,A
INC R0
MOV A,@R0
RLC A
MOV @R0,A
INC R0
MOV A,@R0
RLC A
MOV @R0,A
INC R0
MOV A,@R0
RLC A
MOV @R0,A
INC R0
MOV A,@R0
RLC A
MOV @R0,A
INC R0
MOV A,@R0
RLC A
MOV @R0,A
RET
SUMMA: MOV A,R7
MOV R0,A
CLR C
MOV A,@R0
ADDC A,R1
MOV @R0,A
INC R0
MOV A,@R0
ADDC A,R2
MOV @R0,A
INC R0
MOV A,@R0
ADDC A,R3
MOV @R0,A
INC R0
MOV A,@R0
ADDC A,R4
MOV @R0,A
INC R0
MOV A,@R0
ADDC A,R5
MOV @R0,A
INC R0
MOV A,@R0
ADDC A,R6
MOV @R0,A
RET
showone
Цитата
Вот библиотека с умножения положительных чисел с фиксированной запятой
UMN2_2B - ПРОГРАММА УМНОЖЕНИЯ 2 БАЙТОВОГО ЧИСЛА НА 2 БАЙТОВОЕ.
UMN -ПРОГРАММА УМНОЖЕНИЯ 6 БАЙТОВОГО ЧИСЛА НА 2 БАЙТОВОЕ.
причем из UMN2_2B можно сделать умножение n-БАЙТОВОГО ЧИСЛА НА m-БАЙТОВОЕ.

Но всеже лучше помоему перейти на Си и воспользоваться стандартной библиотекой с плавающей
точкой Keil или IAR.



тут критерий есть, писать только на АСМ, т.к. это вставка в проект, который уже написан на АСМ.
а эта вставка должна выполнять мат операции с числами с фикс запятой.
а т.к. используется C8051F121, то там есть встроенный перемножитель 16*16, т.е. два на два байта.
а мне нужно перемножать 3-и на два байта или три на три байта сфиксированной запятой.

просто раньше так глубоко не влезал в математику для контроллеров.
вот пришлось :-)

всем спасибо за ответ !!!!
mihask
Цитата(showone @ Jan 22 2007, 16:45) *
Цитата

Вот библиотека с умножения положительных чисел с фиксированной запятой
UMN2_2B - ПРОГРАММА УМНОЖЕНИЯ 2 БАЙТОВОГО ЧИСЛА НА 2 БАЙТОВОЕ.
UMN -ПРОГРАММА УМНОЖЕНИЯ 6 БАЙТОВОГО ЧИСЛА НА 2 БАЙТОВОЕ.
причем из UMN2_2B можно сделать умножение n-БАЙТОВОГО ЧИСЛА НА m-БАЙТОВОЕ.

Но всеже лучше помоему перейти на Си и воспользоваться стандартной библиотекой с плавающей
точкой Keil или IAR.



тут критерий есть, писать только на АСМ, т.к. это вставка в проект, который уже написан на АСМ.
а эта вставка должна выполнять мат операции с числами с фикс запятой.
а т.к. используется C8051F121, то там есть встроенный перемножитель 16*16, т.е. два на два байта.
а мне нужно перемножать 3-и на два байта или три на три байта сфиксированной запятой.

просто раньше так глубоко не влезал в математику для контроллеров.
вот пришлось :-)

всем спасибо за ответ !!!!


Если вдруг еще актуально. smile.gif

Умножение можно производить по тому же алгоритму что и умножение столбиком, только если там переполнение которое потом складывается с следующим результатом - это десятки числа, то в
данном случае это старшие два байта числа получившиеся после перемножения. Вот как выглядит
наш столбик:
0x0000 FF01 456D 567E
0x556C 5E67
____________________






;@@@ ###########################
UMN__4__2:
call NACH_ZN

UMN_DP_2B_4B:
CALL SN_WATCH
mov R1,#BUFF2
mov R0,#BUFF1
mov R3,#2
;----------
clr a
push a ;2 push
push a
;----------
clr c

UMN_DP2:
CALL SN_WATCH
anl MCNT1,#0EFH ;CLM
mov MB,@R1
inc R1
mov MB,@R1
dec R1
mov MA,@R0
inc R0
mov MA,@R0
UMN_DP2_1:
mov A,MCNT1
jb ACC.7,UMN_DP2_1
CALL SN_WATCH
inc R0
mov BUFF2+4,MA
mov BUFF2+5,MA
mov BUFF2+6,MA
mov BUFF2+7,MA
clr c
pop a
mov b,a
pop a ;12 pop
addc a,BUFF2+7
mov BUFF2+7,a
mov a,b
addc a,BUFF2+6
mov BUFF2+6,a
clr a
addc a,BUFF2+5
mov BUFF2+5,a
clr a
addc a,BUFF2+4
mov BUFF2+4,a


mov a,BUFF2+7
push a
mov a,BUFF2+6
push a
mov a,BUFF2+5 ;24 push
push a
mov a,BUFF2+4
push a
;!!!!!!;!!!!!!;!!!!!!;!!!!!!
djnz R3,UMN_DP2 ;!!!!!
;!!!!!!;!!!!!!;!!!!!!;!!!!!!
;*******************
mov R0,#BUFF1+5 ;****
mov R3,#6 ;****
;XXXXXXXXXXXXXXXXXXX
; mov DPS,#40h
; mov dptr,#NUMBER+7
;XXXXXXXXXXXXXXXXXXX
UMN_DP2_3: ;****
CALL SN_WATCH ;****
pop a ;****
mov @R0,a ;**** ;8 pop
dec R0 ;****
;XXXXXXXXXXXXXXXXXXX
; movx @dptr,a
; inc dptr
;XXXXXXXXXXXXXXXXXXX
djnz R3,UMN_DP2_3 ;****
;*******************
;XXXXXXXXXXXXXXXXXXX
; mov DPS,#0
;XXXXXXXXXXXXXXXXXXX
;*******************
call KON_ZN
RET
mihask
Цитата(showone @ Jan 22 2007, 16:45) *
Цитата

Вот библиотека с умножения положительных чисел с фиксированной запятой
UMN2_2B - ПРОГРАММА УМНОЖЕНИЯ 2 БАЙТОВОГО ЧИСЛА НА 2 БАЙТОВОЕ.
UMN -ПРОГРАММА УМНОЖЕНИЯ 6 БАЙТОВОГО ЧИСЛА НА 2 БАЙТОВОЕ.
причем из UMN2_2B можно сделать умножение n-БАЙТОВОГО ЧИСЛА НА m-БАЙТОВОЕ.

Но всеже лучше помоему перейти на Си и воспользоваться стандартной библиотекой с плавающей
точкой Keil или IAR.



тут критерий есть, писать только на АСМ, т.к. это вставка в проект, который уже написан на АСМ.
а эта вставка должна выполнять мат операции с числами с фикс запятой.
а т.к. используется C8051F121, то там есть встроенный перемножитель 16*16, т.е. два на два байта.
а мне нужно перемножать 3-и на два байта или три на три байта сфиксированной запятой.

просто раньше так глубоко не влезал в математику для контроллеров.
вот пришлось :-)

всем спасибо за ответ !!!!


Если вдруг еще актуально. smile.gif

Умножение можно производить по тому же алгоритму что и умножение столбиком, только если там переполнение которое потом складывается с следующим результатом - это десятки числа, то в
данном случае это старшие два байта числа получившиеся после перемножения. Вот как выглядит
наш столбик:
0x0000 FF01 456D 567E
x
0x556C 5E67
____________________


Вот пример процедуры умножения в DS80C390, там тоже есть встроенный
перемножитель 16*16



Процедура умножения 32*16

Вход:
Первый множитель BUFF1 - массив 8 байт (число лежит- младший байт в младшем адресе).
Второй множитель BUFF2 - массив 8 байт (число лежит- младший байт в младшем адресе).

Во внутренних регистрах перемножителя:
MB - двухбайтовый регистр первого множителя
MA - двухбайтовый регистр второго множителя он же четырехбайтовый регистр
результата умножения.


UMN__4__2:
UMN_DP_2B_4B:

mov R1,#BUFF2
mov R0,#BUFF1
mov R3,#2
;----------
clr a
push a ;2 push
push a
;----------
clr c

UMN_DP2:
anl MCNT1,#0EFH ;CLM
mov MB,@R1
inc R1
mov MB,@R1
dec R1
mov MA,@R0
inc R0
mov MA,@R0
UMN_DP2_1:
mov A,MCNT1 ; это внутренний флаг окончания процедуры умножения 16*16
jb ACC.7,UMN_DP2_1
inc R0
mov BUFF2+4,MA
mov BUFF2+5,MA
mov BUFF2+6,MA
mov BUFF2+7,MA
clr c
pop a
mov b,a
pop a ;12 pop
addc a,BUFF2+7
mov BUFF2+7,a
mov a,b
addc a,BUFF2+6
mov BUFF2+6,a
clr a
addc a,BUFF2+5
mov BUFF2+5,a
clr a
addc a,BUFF2+4
mov BUFF2+4,a


mov a,BUFF2+7
push a
mov a,BUFF2+6
push a
mov a,BUFF2+5 ;24 push
push a
mov a,BUFF2+4
push a
;!!!!!!;!!!!!!;!!!!!!;!!!!!!
djnz R3,UMN_DP2 ;!!!!!
;!!!!!!;!!!!!!;!!!!!!;!!!!!!
;*******************
mov R0,#BUFF1+5 ;****
mov R3,#6 ;****
UMN_DP2_3: ;****
pop a ;****
mov @R0,a ;**** ;8 pop
dec R0 ;****
djnz R3,UMN_DP2_3 ;****
;*******************
RET
showone
огромное всем СПАСИБО
разобрался :-)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.