реклама на сайте
подробности

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Операции над большими числами, Операции над большими числами
NickSmith
сообщение Mar 9 2010, 21:25
Сообщение #16


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 21-10-09
Пользователь №: 53 117



Цитата(=GM= @ Mar 9 2010, 23:29) *
Правильно так: (5050/10^8)*2^28 =0x13BA0000000/0x5F5E100=0x34F4=13556

А я вот тут подумал, а если подойти к задаче с дугой стороны.
Я посмотрел, что прибавление или вычитание из кода идет с шагом или 2 или 3.
Закономерность вроде как тоже есть.. Изменение на 2 происходит после двух подряд изменений на три и так пять раз, после чего три раза подряд изменение на три и цикл снова..
2333 233 233 233 233 233 23332......
Может быть по такому пути проще идти и не городить огород со сложной математикой..
Только как бы это привязать к какому либо значению?? Или придется тупо на каких то хитрых циклах делать??

Сообщение отредактировал NickSmith - Mar 9 2010, 21:26
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Mar 9 2010, 21:31
Сообщение #17


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(NickSmith @ Mar 10 2010, 00:25) *
Только как бы это привязать к какому либо значению?? Или придется тупо на каких то хитрых циклах делать??

Фигней не надо заниматься, а ? Всего-то нужно тривиальное деление 40 / 20 битов. Простейший цикл сдвиг-сравнение-вычитание.
Go to the top of the page
 
+Quote Post
NickSmith
сообщение Mar 9 2010, 21:33
Сообщение #18


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 21-10-09
Пользователь №: 53 117



Цитата(rx3apf @ Mar 10 2010, 00:31) *
Фигней не надо заниматься, а ? Всего-то нужно тривиальное деление 40 / 20 битов. Простейший цикл сдвиг-сравнение-вычитание.

А по подробней можно??
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Mar 9 2010, 22:55
Сообщение #19


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(NickSmith @ Mar 10 2010, 00:33) *
А по подробней можно??

Ну как делается деление "столбиком" ? Так и здесь - сдвигаем делимое в накопитель остатка, сравниваем остаток с делимым, если больше либо равен - вычитаем делимое из остатка и записываем "1" в результат. Иначе не вычитаем и записываем "0". Для удобства регистр делителя и результата совмещается, по окончанию операции частное будет в том же накопителе. Реализации под конкретную платформу - практически всегда есть в аппликухах...
Go to the top of the page
 
+Quote Post
NickSmith
сообщение Mar 9 2010, 23:03
Сообщение #20


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 21-10-09
Пользователь №: 53 117



Цитата(rx3apf @ Mar 10 2010, 01:55) *
Ну как делается деление "столбиком" ? Так и здесь - сдвигаем делимое в накопитель остатка, сравниваем остаток с делимым, если больше либо равен - вычитаем делимое из остатка и записываем "1" в результат. Иначе не вычитаем и записываем "0". Для удобства регистр делителя и результата совмещается, по окончанию операции частное будет в том же накопителе. Реализации под конкретную платформу - практически всегда есть в аппликухах...

Т.е делать все по формуле..
Хорошо, а как быт с округлением результатов? у меня же ведь на выходе получается число с запятой.. А в демо программе, как я понял результат расчетов округляется или в большую или в меньшую сторону?
Как поделить и умножить я разберусь, а вот как быть с остатком..
Я делаю это на tiny2313 там есть пример математики с большими числами.. Но он очень громоздок.. Что то строк под 150 по моему.. По этому я и подумал пойти простым путем и поиграть с увеличением или уменьшением готовой константы.. Кода по моему всяко меньше получится??
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 10 2010, 01:09
Сообщение #21


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



[attachment=41648:34335.zip]
Цитата
Приближение действительного числа рациональными дробями с заданным ограничением для знаменателя
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Mar 10 2010, 06:10
Сообщение #22


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Цитата
tiny2313

Взяли бы мегу восьмую и писали на WinAVR - достаточно эффективные встроенные функции деления 64/64 есть.
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Mar 10 2010, 07:44
Сообщение #23


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(NickSmith @ Mar 10 2010, 02:03) *
Т.е делать все по формуле..
Хорошо, а как быт с округлением результатов? у меня же ведь на выходе получается число с запятой.. А в демо программе, как я понял результат расчетов округляется или в большую или в меньшую сторону?
Как поделить и умножить я разберусь, а вот как быть с остатком..

Я уже говорил, как это сделать проще. Делимое взять вдвое больше, а после деления частное еще раз поделить вдвое простым сдвигом и по состоянию бита переноса добавить единичку к результату.
Цитата
Я делаю это на tiny2313 там есть пример математики с большими числами.. Но он очень громоздок.. Что то строк под 150 по моему..

Жуть какая... Вот деление 32 / 16. Добавить по одному регистру в делимое, частное и остаток, будет требуемые 40 / 24...
CODE

;----------------------------------------------------------------------
; Деление XH:XL:YH:YL / ZH:ZL
; Используются регистры r0, r1, temp
;----------------------------------------------------------------------

Div32:
clr r0
clr r1
ldi temp,32 ; счетчик
Div32_1:
lsl YL
rol YH
rol XL
rol XH ; сдвиг делимого
rol r1
rol r0 ; и остатка (r0:r1)
cp r1,ZL
cpc r0,ZH ; можно вычесть делитель ?
brlo Div32_2 ; нет
ori YL,$01 ; иначе "1" в частное
sub r1,ZL
sbc r0,ZH
Div32_2:
dec temp
brne Div32_1 ; цикл деления

; В XH:XL:YH:YL содержится результат деления

ret
Go to the top of the page
 
+Quote Post
NickSmith
сообщение Mar 10 2010, 10:48
Сообщение #24


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 21-10-09
Пользователь №: 53 117



Цитата(rx3apf @ Mar 10 2010, 10:44) *
Я уже говорил, как это сделать проще. Делимое взять вдвое больше, а после деления частное еще раз поделить вдвое простым сдвигом и по состоянию бита переноса добавить единичку к результату.

Жуть какая... Вот деление 32 / 16. Добавить по одному регистру в делимое, частное и остаток, будет требуемые 40 / 24...

Огромное спасибо за пример..
Но я все равно под запутался. Выше писали:
Цитата
Правильно так: (5050/10^8)*2^28 =0x13BA 0000 000/0x5F5E100=0x34F4=13556

Но получается не 0x34F4, 0x34F3
Вот если взять делимое на 1 ноль больше, то результат будет 0x34f3f
Если младшую тетраду младшего байта как то обрабатывать по условию, то и получится округление.. Прав??
Go to the top of the page
 
+Quote Post
rx3apf
сообщение Mar 10 2010, 10:56
Сообщение #25


Гуру
******

Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047



Цитата(NickSmith @ Mar 10 2010, 13:48) *
Но получается не 0x34F4, 0x34F3
Вот если взять делимое на 1 ноль больше, то результат будет 0x34f3f
Если младшую тетраду младшего байта как то обрабатывать по условию, то и получится округление.. Прав??

Мать-перемать... Ну сколько можно объяснять ? Надо взять делимое вдвое больше (умножить на 2^29), а потом частное поделить еще на 2 сдвигом вправо, и по состоянию переноса прибавить или не прибавляь 1 (т.е. для avr сделать adc. Для приведенной мной программы - lsr xh ror xl ror yh ror yl adc yl,temp adc yh,temp adc xl,temp adc xh temp). Конеччно, это можно сделать и контролем остатка, но так - проще. Естественно, в примере с конкретными числами разрядность можно сократить на 8 битов, поэтому достаточно деление 40 / 24.

Сообщение отредактировал rx3apf - Mar 10 2010, 10:57
Go to the top of the page
 
+Quote Post
NickSmith
сообщение Mar 10 2010, 11:01
Сообщение #26


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 21-10-09
Пользователь №: 53 117



Цитата(rx3apf @ Mar 10 2010, 13:56) *
Мать-перемать... Ну сколько можно объяснять ? Надо взять делимое вдвое больше (умножить на 2^29), а потом частное поделить еще на 2 сдвигом вправо, и по состоянию переноса прибавить или не прибавляь 1 (т.е. для avr сделать adc. Для приведенной мной программы - lsr xh ror xl ror yh ror yl adc yl,temp adc yh,temp adc xl,temp adc xh temp). Конеччно, это можно сделать и контролем остатка, но так - проще. Естественно, в примере с конкретными числами разрядность можно сократить на 8 битов, поэтому достаточно деление 40 / 24.

Все, теперь понял ход вашей мысли..
Go to the top of the page
 
+Quote Post
ae_
сообщение Mar 10 2010, 15:14
Сообщение #27


Участник
***

Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695



Цитата(NickSmith @ Mar 10 2010, 19:01) *
Все, теперь понял ход вашей мысли..

Если я правильно понял, нужно вычислять выражение вида a*b/c, где a - частота, которую нужно получить, b - разрядность 28 bit, c - частота кварца. Причём, b и c - константы. вычисляем b/c = 2^28/10^8 = 2.68435456. Получается, нужно только одно умножение a*k, где k=2.68435456. проверяем для 5050*k=13555.990528.
Так как плавающая точка всё равно не нужна и в синтезатор загружаем целые числа, то вместо k надо взять N=k<<16 или k<<24 или сколько там нужно разрядов для этого синтезатора, и работаем только с целочисленным умножением. Пример для 16-bit результата: N=k*2^16=0x2AF32, 5050*N=0x34F40054, старшие два байта и есть искомое 0x34F4
Go to the top of the page
 
+Quote Post
NickSmith
сообщение Mar 10 2010, 17:12
Сообщение #28


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 21-10-09
Пользователь №: 53 117



Цитата(ae_ @ Mar 10 2010, 18:14) *
Если я правильно понял, нужно вычислять выражение вида a*b/c, где a - частота, которую нужно получить, b - разрядность 28 bit, c - частота кварца. Причём, b и c - константы. вычисляем b/c = 2^28/10^8 = 2.68435456. Получается, нужно только одно умножение a*k, где k=2.68435456. проверяем для 5050*k=13555.990528.
Так как плавающая точка всё равно не нужна и в синтезатор загружаем целые числа, то вместо k надо взять N=k<<16 или k<<24 или сколько там нужно разрядов для этого синтезатора, и работаем только с целочисленным умножением. Пример для 16-bit результата: N=k*2^16=0x2AF32, 5050*N=0x34F40054, старшие два байта и есть искомое 0x34F4

Изящный способ, но у него с округлением проблемы... А у меня это критично.. Хотя так конечно было бы проще..
Go to the top of the page
 
+Quote Post
ae_
сообщение Mar 10 2010, 17:27
Сообщение #29


Участник
***

Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695



Цитата(NickSmith @ Mar 11 2010, 01:12) *
Изящный способ, но у него с округлением проблемы... А у меня это критично.. Хотя так конечно было бы проще..

С округлением всё просто, стрший бит отбрасываемой части прибавляем к результату, и всё.
Go to the top of the page
 
+Quote Post
NickSmith
сообщение Mar 10 2010, 19:44
Сообщение #30


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 21-10-09
Пользователь №: 53 117



С одним вроде как все понятно теперь, но вот теперь засада с другим вычислением..

Для вычисления значения фазы существует формула:
значение регистра фазы = (значение фазы *4096)/2Пи и Но получается полная ерунда.. С их расчетами никак не сходится.. Например значение регистра для фазы 90 градусов получается 0х0400 в их примерах.
Если же делать по этой формуле то получается 58671 или 0xE52F
Что не так?
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 17:44
Рейтинг@Mail.ru


Страница сгенерированна за 0.01518 секунд с 7
ELECTRONIX ©2004-2016