NickSmith 0 8 марта, 2010 Опубликовано 8 марта, 2010 · Жалоба Для программирования DDS синтезатора, мне надо вычислять код частоты.. Исходные: Есть константа в виде 5050. Далее мне нужно эту константу разделить на 1000 затем полученный результат разделить на 1 умноженную на 2^28 У полученного результата то что будет после запятой округлить в большую сторону.. Как все это выполнить на асме?? Я нашел только стандартные процедуры деления, которые описаны в апнотах. Но у них нет деления для нецелых числе. Точней только для 1 байтных чисел есть.. Подскажите, как бы все это реализовать?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rx3apf 0 8 марта, 2010 Опубликовано 8 марта, 2010 · Жалоба Подскажите, как бы все это реализовать?? Или плавучку делать, или изначально умножить делимое на двойку соответствующей степени, таким образом, чтобы после всех делений результат оставался целым с требуемой точностью. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NickSmith 0 8 марта, 2010 Опубликовано 8 марта, 2010 · Жалоба Или плавучку делать, или изначально умножить делимое на двойку соответствующей степени, таким образом, чтобы после всех делений результат оставался целым с требуемой точностью. Не очень понимаю как это должно выглядеть?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rx3apf 0 8 марта, 2010 Опубликовано 8 марта, 2010 · Жалоба Не очень понимаю как это должно выглядеть?? Нужно поделить 5050 на 1000 без потери значимости ? Множим 5050 на 2^10 (5171200, или 4EE800 hex), полученное число делим на 1000. Получилось 5171. Однако результат только выглядит как целое число, а на самом деле это дробное значение 5.0498, в формате 6.10 (двоичных разрядов). Должным образом масштабируя исходные данные, можно работать с дробными числами с помощью простой целочисленной арифметики. Ну, а если нужно что-то серьезное - тогда делать плавучку... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NickSmith 0 8 марта, 2010 Опубликовано 8 марта, 2010 (изменено) · Жалоба Должным образом масштабируя исходные данные, можно работать с дробными числами с помощью простой целочисленной арифметики. Ну, а если нужно что-то серьезное - тогда делать плавучку... А где бы об этом почитать?? Не очень понятно как возникает степень 2, от чего я отталкиваюсь?? Мою задачу можно решить подобным образом?? Изменено 8 марта, 2010 пользователем NickSmith Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rx3apf 0 8 марта, 2010 Опубликовано 8 марта, 2010 (изменено) · Жалоба А где бы об этом почитать?? Не очень понятно как возникает степень 2, от чего я отталкиваюсь?? Степень двойки выбирается, исходя из требуемой разрядности и точности промежуточных и окончательного результата. В моем примере можно было бы взять не 2^10, а, скажем, 2^12, тогда результат был бы 20684, это было бы то же самое число 5.0498, но в формате 4.12. Однако результат округлен неправильно (взята только целая часть), поэтому точности это не прибавило. Надо бы взять 2^13, а после деления на 1000 еще поделить на 2 простым сдвигом и округлить (это проще, чем проверять остаток от деления). И результат станет 5.0500 (в формате 4.12). Где почитать - так вот сейчас не подскажу, кажется, я в это вникал по каким-то аппликухам к MSP430 (много лет прошло, уж не помню). Мою задачу можно решить подобным образом?? Почему нет ? Простая арифметика, надо просто прикинуть требуемые разрядности, превратить простым умножением на константу (2 в подходящей степени) все дробные значения в целые и с ними работать. Изменено 8 марта, 2010 пользователем rx3apf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NickSmith 0 9 марта, 2010 Опубликовано 9 марта, 2010 · Жалоба Почему нет ? Простая арифметика, надо просто прикинуть требуемые разрядности, превратить простым умножением на константу (2 в подходящей степени) все дробные значения в целые и с ними работать. А я думаю, а если как то сократить мою формулу.. Она рассчитана на 4 байтовые числа, в моем же случае результат в основном двухбайтовый.. Я не могу сообразить, с какой стороны к этому подходить?? Еще как вариант, увеличение и уменьшение уже готового числа, но дело в том, что шаг как я пронаблюдал всегда разный. Иногда на два а иногда и на пять.. Это нужно какой то анализ проводить.. По моему проще вычислять по формуле нужное значение.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
cant_101 0 9 марта, 2010 Опубликовано 9 марта, 2010 · Жалоба Вам нужно не числа сокращать, а формулу. Тобишь оптимизировать вычисления. Гуглите в сторону чисел с фиксированной запятой, про что Вам rx3apf и говорит Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 9 марта, 2010 Опубликовано 9 марта, 2010 · Жалоба Есть константа в виде 5050. Далее мне нужно эту константу разделить на 1000 затем полученный результат разделить на 1 умноженную на 2^28. У полученного результата то что будет после запятой округлить в большую сторону. Поточнее определите, что вам нужно. Следуя вашей формуле, вы получите значение (5050/1000)/2^28=1.88127Е-8, по-моему это не то число, которое вы ожидали. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NickSmith 0 9 марта, 2010 Опубликовано 9 марта, 2010 (изменено) · Жалоба Поточнее определите, что вам нужно. Следуя вашей формуле, вы получите значение (5050/1000)/2^28=1.88127Е-8, по-моему это не то число, которое вы ожидали. Действительно ошибся. Не на 1000 а на 100. Получится 13555,99053 а если округлить то 13556 в шестнадцатеричном будет 34F4 Изменено 9 марта, 2010 пользователем NickSmith Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 9 марта, 2010 Опубликовано 9 марта, 2010 · Жалоба Как вы вычисляете-то? Что ж из вас ответы клещами приходится тянуть! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NickSmith 0 9 марта, 2010 Опубликовано 9 марта, 2010 (изменено) · Жалоба Как вы вычисляете-то? Что ж из вас ответы клещами приходится тянуть! Так как же мне это злодейство побороть.. Уже пол дня в раздумьях и гуглении нахожусь и ничего толкового пока что не нашел.. Поточнее определите, что вам нужно. Следуя вашей формуле, вы получите значение (5050/1000)/2^28=1.88127Е-8, по-моему это не то число, которое вы ожидали. И опять я ошибся Правильно это будет выглядеть так: (5050/10^8)/1*2^28 Если это делать без единицы, то получается ерунда почему то.. формула выглядит так Значение регистра = выходная частота в мегагерцах/ частота тактового генератора в мегагерцах*2^28 У меня же частоты в герцах и получается буквально одно слово.. Частота тактового генератора в а моем случае 1 мегагерц Изменено 9 марта, 2010 пользователем NickSmith Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rx3apf 0 9 марта, 2010 Опубликовано 9 марта, 2010 · Жалоба И опять я ошибся Правильно это будет выглядеть так: (5050/10^8)/1*2^28 Если это делать без единицы, то получается ерунда почему то.. А "с единицей" - так не просто ерунда, а вообще просто форменный бред, поскольку практического смысла умножение не единицу не имеет. Приведенная формула тоже никуда не годится - все ж в регистр синтезатора загружают целое число, а тут в любом случае дробное (и очень маленькое). Короче, разбирайтесь с математикой, и лишь потом - с переложением _правильных_ формул в их реализацию для микроконтроллера... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
NickSmith 0 9 марта, 2010 Опубликовано 9 марта, 2010 (изменено) · Жалоба А "с единицей" - так не просто ерунда, а вообще просто форменный бред, поскольку практического смысла умножение не единицу не имеет. Приведенная формула тоже никуда не годится - все ж в регистр синтезатора загружают целое число, а тут в любом случае дробное (и очень маленькое). Короче, разбирайтесь с математикой, и лишь потом - с переложением _правильных_ формул в их реализацию для микроконтроллера... Ну да целое число. То, что после запятой округляется или в большую или в меньшую сторону... Я думаю так сделать: я храню значение в виде 5050, на самом деле это для формулы должно быть 10^-8 т.е я могу 5050/1*2^28 полученный результат разделить на 10^8.. Но тут возникают вопросы, как мне округлить числа после запятой?? И может быть как то можно это все сократить?? Я тоже так подумал, что с 1 единицей что без нее разницы нет.. Но вот попробуйте в экселе это сделать без нее.. Тогда действительно бред Изменено 9 марта, 2010 пользователем NickSmith Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 9 марта, 2010 Опубликовано 9 марта, 2010 · Жалоба Правильно так: (5050/10^8)*2^28 =0x13BA0000000/0x5F5E100=0x34F4=13556 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться