NickSmith 0 9 марта, 2010 Опубликовано 9 марта, 2010 (изменено) · Жалоба Правильно так: (5050/10^8)*2^28 =0x13BA0000000/0x5F5E100=0x34F4=13556 А я вот тут подумал, а если подойти к задаче с дугой стороны. Я посмотрел, что прибавление или вычитание из кода идет с шагом или 2 или 3. Закономерность вроде как тоже есть.. Изменение на 2 происходит после двух подряд изменений на три и так пять раз, после чего три раза подряд изменение на три и цикл снова.. 2333 233 233 233 233 233 23332...... Может быть по такому пути проще идти и не городить огород со сложной математикой.. Только как бы это привязать к какому либо значению?? Или придется тупо на каких то хитрых циклах делать?? Изменено 9 марта, 2010 пользователем NickSmith Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rx3apf 0 9 марта, 2010 Опубликовано 9 марта, 2010 · Жалоба Только как бы это привязать к какому либо значению?? Или придется тупо на каких то хитрых циклах делать?? Фигней не надо заниматься, а ? Всего-то нужно тривиальное деление 40 / 20 битов. Простейший цикл сдвиг-сравнение-вычитание. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NickSmith 0 9 марта, 2010 Опубликовано 9 марта, 2010 · Жалоба Фигней не надо заниматься, а ? Всего-то нужно тривиальное деление 40 / 20 битов. Простейший цикл сдвиг-сравнение-вычитание. А по подробней можно?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rx3apf 0 9 марта, 2010 Опубликовано 9 марта, 2010 · Жалоба А по подробней можно?? Ну как делается деление "столбиком" ? Так и здесь - сдвигаем делимое в накопитель остатка, сравниваем остаток с делимым, если больше либо равен - вычитаем делимое из остатка и записываем "1" в результат. Иначе не вычитаем и записываем "0". Для удобства регистр делителя и результата совмещается, по окончанию операции частное будет в том же накопителе. Реализации под конкретную платформу - практически всегда есть в аппликухах... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NickSmith 0 9 марта, 2010 Опубликовано 9 марта, 2010 · Жалоба Ну как делается деление "столбиком" ? Так и здесь - сдвигаем делимое в накопитель остатка, сравниваем остаток с делимым, если больше либо равен - вычитаем делимое из остатка и записываем "1" в результат. Иначе не вычитаем и записываем "0". Для удобства регистр делителя и результата совмещается, по окончанию операции частное будет в том же накопителе. Реализации под конкретную платформу - практически всегда есть в аппликухах... Т.е делать все по формуле.. Хорошо, а как быт с округлением результатов? у меня же ведь на выходе получается число с запятой.. А в демо программе, как я понял результат расчетов округляется или в большую или в меньшую сторону? Как поделить и умножить я разберусь, а вот как быть с остатком.. Я делаю это на tiny2313 там есть пример математики с большими числами.. Но он очень громоздок.. Что то строк под 150 по моему.. По этому я и подумал пойти простым путем и поиграть с увеличением или уменьшением готовой константы.. Кода по моему всяко меньше получится?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 10 марта, 2010 Опубликовано 10 марта, 2010 · Жалоба Приближение действительного числа рациональными дробями с заданным ограничением для знаменателя Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 10 марта, 2010 Опубликовано 10 марта, 2010 · Жалоба tiny2313 Взяли бы мегу восьмую и писали на WinAVR - достаточно эффективные встроенные функции деления 64/64 есть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rx3apf 0 10 марта, 2010 Опубликовано 10 марта, 2010 · Жалоба Т.е делать все по формуле.. Хорошо, а как быт с округлением результатов? у меня же ведь на выходе получается число с запятой.. А в демо программе, как я понял результат расчетов округляется или в большую или в меньшую сторону? Как поделить и умножить я разберусь, а вот как быть с остатком.. Я уже говорил, как это сделать проще. Делимое взять вдвое больше, а после деления частное еще раз поделить вдвое простым сдвигом и по состоянию бита переноса добавить единичку к результату. Я делаю это на tiny2313 там есть пример математики с большими числами.. Но он очень громоздок.. Что то строк под 150 по моему.. Жуть какая... Вот деление 32 / 16. Добавить по одному регистру в делимое, частное и остаток, будет требуемые 40 / 24... ;---------------------------------------------------------------------- ; Деление 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NickSmith 0 10 марта, 2010 Опубликовано 10 марта, 2010 · Жалоба Я уже говорил, как это сделать проще. Делимое взять вдвое больше, а после деления частное еще раз поделить вдвое простым сдвигом и по состоянию бита переноса добавить единичку к результату. Жуть какая... Вот деление 32 / 16. Добавить по одному регистру в делимое, частное и остаток, будет требуемые 40 / 24... Огромное спасибо за пример.. Но я все равно под запутался. Выше писали: Правильно так: (5050/10^8)*2^28 =0x13BA 0000 000/0x5F5E100=0x34F4=13556 Но получается не 0x34F4, 0x34F3 Вот если взять делимое на 1 ноль больше, то результат будет 0x34f3f Если младшую тетраду младшего байта как то обрабатывать по условию, то и получится округление.. Прав?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rx3apf 0 10 марта, 2010 Опубликовано 10 марта, 2010 (изменено) · Жалоба Но получается не 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. Изменено 10 марта, 2010 пользователем rx3apf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NickSmith 0 10 марта, 2010 Опубликовано 10 марта, 2010 · Жалоба Мать-перемать... Ну сколько можно объяснять ? Надо взять делимое вдвое больше (умножить на 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. Все, теперь понял ход вашей мысли.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ae_ 2 10 марта, 2010 Опубликовано 10 марта, 2010 · Жалоба Все, теперь понял ход вашей мысли.. Если я правильно понял, нужно вычислять выражение вида 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NickSmith 0 10 марта, 2010 Опубликовано 10 марта, 2010 · Жалоба Если я правильно понял, нужно вычислять выражение вида 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 Изящный способ, но у него с округлением проблемы... А у меня это критично.. Хотя так конечно было бы проще.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ae_ 2 10 марта, 2010 Опубликовано 10 марта, 2010 · Жалоба Изящный способ, но у него с округлением проблемы... А у меня это критично.. Хотя так конечно было бы проще.. С округлением всё просто, стрший бит отбрасываемой части прибавляем к результату, и всё. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NickSmith 0 10 марта, 2010 Опубликовано 10 марта, 2010 · Жалоба С одним вроде как все понятно теперь, но вот теперь засада с другим вычислением.. Для вычисления значения фазы существует формула: значение регистра фазы = (значение фазы *4096)/2Пи и Но получается полная ерунда.. С их расчетами никак не сходится.. Например значение регистра для фазы 90 градусов получается 0х0400 в их примерах. Если же делать по этой формуле то получается 58671 или 0xE52F Что не так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться