|
Умножение дробных чисел |
|
|
|
May 29 2007, 05:39
|
Участник

Группа: Участник
Сообщений: 37
Регистрация: 13-04-07
Пользователь №: 27 012

|
Добрый день!
Необходимо разделить число на 5, т.е. умножить на 0,2. Но я не могу получить ровно 0,2 при переводе числа в дробное по методу ATMEL (Appl. Note 201).
Погрешность которая получается не устраивает, т.к. числа, которые необходимо делить на 5 находятся в диапазоне 1..100, соответственно набегает ошибка около 35.
Есть ли какой-то выход из этой ситуации ?
Спасибо
|
|
|
|
|
May 29 2007, 06:15
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 31-05-06
Пользователь №: 17 614

|
Цитата(golovin @ May 29 2007, 11:39)  Добрый день!
Необходимо разделить число на 5, т.е. умножить на 0,2. Но я не могу получить ровно 0,2 при переводе числа в дробное по методу ATMEL (Appl. Note 201).
Погрешность которая получается не устраивает, т.к. числа, которые необходимо делить на 5 находятся в диапазоне 1..100, соответственно набегает ошибка около 35.
Есть ли какой-то выход из этой ситуации ?
Спасибо лично я бы сделал так, делимое умножал 100,а делитель оставлял как есть(5),а полученный результат был в формате z*10-2(99*100/5=1980*0,01). для работы с большими числами пользовался маленькой библиотечкой,точнее копи-пастил нужные куски (там написано сложение,вычитание,деление,умножение 32битных чисел,перевод BCD2bin и Bin2BCD всё на ассемблере)
|
|
|
|
|
May 29 2007, 06:18
|
Участник

Группа: Участник
Сообщений: 37
Регистрация: 13-04-07
Пользователь №: 27 012

|
В App.Note как раз описана технология перевода дробных чисел в формат, который используют мк. Если коротко, то старший бит 7 = 2^0 =1, следующий 6 = 2^-1 = 0.5 ... 0 = 2^-7 = 0.0078125, таким образом записав соответствующие 1 и 0 в нужные биты получам дробное число, которое используется в команде FMUL или FMULS. Например, 0.75 = 01100000.
|
|
|
|
|
May 29 2007, 06:20
|
Знающий
   
Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693

|
Цитата(Диm @ May 29 2007, 10:15)  лично я бы сделал так, делимое умножал 100,а делитель оставлял как есть(5),а полученный результат был в формате z*10-2(99*100/5=1980*0,01). для работы с большими числами пользовался маленькой библиотечкой,точнее копи-пастил нужные куски (там написано сложение,вычитание,деление,умножение 32битных чисел,перевод BCD2bin и Bin2BCD всё на ассемблере) Не надо делитель ;О) Деление в 8-15 раз(зависит от писателя) медленнее умножения. Длиннее, больше жрёт ресурсов...Ацтой, короче.
|
|
|
|
|
May 29 2007, 06:25
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 31-05-06
Пользователь №: 17 614

|
Цитата(mse @ May 29 2007, 12:20)  Не надо делитель ;О) Деление в 8-15 раз(зависит от писателя) медленнее умножения. Длиннее, больше жрёт ресурсов...Ацтой, короче. не спорю!может тут надо считать десять раз в секунду,не более этого.тогда это самое простое помоему
|
|
|
|
|
May 29 2007, 07:43
|
Участник

Группа: Участник
Сообщений: 37
Регистрация: 13-04-07
Пользователь №: 27 012

|
К сожалению программное умножение/деление не подходит из-за медлительности.
|
|
|
|
|
May 29 2007, 08:04
|
Участник
  
Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695

|
Цитата(golovin @ May 29 2007, 16:43)  К сожалению программное умножение/деление не подходит из-за медлительности. Умножение выполняется всего за 2 такта, о какой медлительности идёт речь? Код LDI DELIMOE, 100 LDI DELITEL, 256/5 MUL DELIMOE, DELITEL В регистре R1 будет результат 100/5=20
|
|
|
|
|
May 29 2007, 08:06
|
Участник

Группа: Участник
Сообщений: 37
Регистрация: 13-04-07
Пользователь №: 27 012

|
Т.е. любая мега сможет поделить на 5 или умножить на 0,2 программно за 16 тактов ? Не подскажите, где можно найти такой код ? И точность не подскажите? Цитата(ae_ @ May 29 2007, 12:04)  Умножение выполняется всего за 2 такта, о какой медлительности идёт речь? Код LDI DELIMOE, 100 LDI DELITEL, 256/5 MUL DELIMOE, DELITEL В регистре R1 будет результат 100/5=20 Я вроде писал о ПРОГРАММНОМ умножении, а не АППАРАТНОМ А приведённый код даст следующее : Delitel = $33 = 51 Результат : R1 = $13, R2 = $EC
Сообщение отредактировал golovin - May 29 2007, 08:11
|
|
|
|
|
May 29 2007, 08:18
|
Знающий
   
Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693

|
Цитата(golovin @ May 29 2007, 12:06)  Т.е. любая мега сможет поделить на 5 или умножить на 0,2 программно за 16 тактов ? Не подскажите, где можно найти такой код ? И точность не подскажите? Да. берём число N и умножаем на 0х34(256/5+1) или на 0х3334(65536/5+1). От результата помножения берём старший байт. Думаю, если не надо иметь десятые, то 0х34 будет достаточно. Есть такой пласт знаний:AVR200.asm, AVR200b.asm, AVR201.asm. Находится в Аппнотах АСМа Астудии. Цитата Я вроде писал о ПРОГРАММНОМ умножении, а не АППАРАТНОМ Щас только тиньки обделены умножителем. Ну, на худой конец, рукопашный умножитель 16Х8 будет тактов 60-70. 8х8 тама 34 такта рукопашных.
|
|
|
|
|
May 29 2007, 08:21
|
Участник
  
Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695

|
Цитата(golovin @ May 29 2007, 17:06)  Т.е. любая мега сможет поделить на 5 или умножить на 0,2 программно за 16 тактов ? Не подскажите, где можно найти такой код ? И точность не подскажите? Я вроде писал о ПРОГРАММНОМ умножении, а не АППАРАТНОМ
А приведённый код даст следующее :
Delitel = $33 = 51
Результат : R1 = $13, R2 = $EC Результат R1=19 (целая часть), R0(не R2)=236/256=0,921875 - дробная часть. Точность равна единице млашего разряда =1/256 при условии, что делитель точный. У вас делитель =51 вместо 51.2, так что точность будет меньше. Если такая точность не устраивает, в формате 8.8, используйте 8.16. В этом случае надо умножать делимое на 65336/5, результат будет 3-х байтный, старший байт - целая часть, два младших - дробная.
|
|
|
|
|
May 29 2007, 08:25
|
Знающий
   
Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693

|
Цитата(ae_ @ May 29 2007, 12:21)  Результат R1=19 (целая часть), R0(не R2)=236/256=0,921875 - дробная часть. Точность равна единице млашего разряда =1/256 при условии, что делитель точный. У вас делитель =51 вместо 51.2, так что точность будет меньше. Если такая точность не устраивает, в формате 8.8, используйте 8.16. В этом случае надо умножать делимое на 65336/5, результат будет 3-х байтный, старший байт - целая часть, два младших - дробная. Будет то-же самое, только вид сбоку. ;О) надо множить на 256/5+1. На худой конец, к старшему дробному байту мона прибавлять 0х80, а к результату, с переносом, 0х0. Но это фигня лишняя.
|
|
|
|
|
May 29 2007, 08:31
|
Участник

Группа: Участник
Сообщений: 37
Регистрация: 13-04-07
Пользователь №: 27 012

|
to mse: по поводу программного и аппаратного это я не Вам
По поводу App.Note'ов - читал. По поводу R2 - опечатался.
В том то и дело, что нужно определить числа кратные 5. А такой метод не даёт точности. Т. е. если R0 = 0 - кратное. А так приходится вводить некую дельту и плясать вокруг неё. А это время.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|