|
Сплош и рядом математика, помогите кто чем может |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 19)
|
Jul 8 2006, 18:11
|
Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 5-05-06
Из: Ekaterinburg, Russia
Пользователь №: 16 821

|
А может просто глянуть Кнута?
--------------------
Чудес не бывает - бывает мало знаний и опыта!
|
|
|
|
|
Jul 9 2006, 18:28
|
Частый гость
 
Группа: Свой
Сообщений: 148
Регистрация: 26-05-05
Пользователь №: 5 416

|
по повду кнута - чего то я часто вижу этого автора на страницах форума, но ни одной ссылки на него... если бы был кнут, то я обязательно его глянул бы... Yura_K, может кинеш линк на него?
zltigo - зачот, но к теме не относится...
Atashi, действительно...
LordN, я так понимаю, что сайт - это твоё детище... как говорится охайо, обязательно гляну...
trablik, эта мысль приходила и мне в голову, но есть несколько но - прибор у меня конечно же не прецизионный, но точность мне необходима большая, а следовательно и такихзначений будет свыше трёх тысяч.... что не то что в микрокотроллере сохранить, а вообще просчитать (бех автоматизиции есессно) сложновато...
всем спазибо за отклики... тема считается открытой для дальнейших обсуждений...
|
|
|
|
|
Jul 9 2006, 20:16
|
Частый гость
 
Группа: Свой
Сообщений: 114
Регистрация: 29-09-05
Пользователь №: 9 092

|
Цитата(UniBomb @ Jul 9 2006, 22:28)  trablik, эта мысль приходила и мне в голову, но есть несколько но - прибор у меня конечно же не прецизионный, но точность мне необходима большая, а следовательно и такихзначений будет свыше трёх тысяч.... что не то что в микрокотроллере сохранить, а вообще просчитать (бех автоматизиции есессно) сложновато... по поводу необходимости более трёх тысяч значений- не обязательно всё делать в лоб. Если вспомнить из математики формулу ln( a*b )=ln( a )+ln( b ), то задачу можно существенно упростить, раскладывая аргумент логарифма на множители. Поясню на примере. Пусть требуется вычислить ln(123456.789). Решение: ln(123456)=ln(10*10*10*10*10*1.23456789)= ln(10)+ln(10)+ln(10)+ln(10)+ln(10) + ln(1.23456789)=5*ln(10)+ ln(1.23456789) Константу ln(10) монжо вычислить заранее с высокой точностью. Таким образом, для вычисления логарифма любого числа потребуется знание константы ln(10) и вычисление логарифма числа на отрезке от 1 до 10, а это гораздо проще. Примечание. В случае чисел меньших 1 для приведения их к диапазону 1..10 нужно не прибалять, а вычитать ln(10).
|
|
|
|
|
Jul 9 2006, 21:39
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(UniBomb @ Jul 9 2006, 23:27)  zltigo, опять зачот... но снова нето... нету библиотечной функции... я работаю в среде AVRStudio, использующий язык assembler... А что, объектные файлы студийный ассемблер исключительно собственного формата генерит и его линкер ничего кроме них не переваривает? Если не обе этих проблемы сразу, то можно и постороннюю прилинковать. В общем слинковать через конвертер ELF можно: Installing and using AVRGCC with AVRstudio This is a comprehensive introduction on how to install AVRstudio and and the GNU AVR C compiler “avr-gcc”, and making them work together. This introduction leads step by step to the successful build of sample code, and programming of whichever AVR part you have chosen, on the STK500 development board. Used in this introduction: • AVRstudio executable installer, “astudio.exe” release 3.53 of nov.8, 2001[5.9M] or later. Downloadable from www.avrfreaks.net • AVRGCC executable installer “avrgcc200112XXa_AVRfreaks.exe” [8.1M], AVRfreaks distribution of dec.07, 2001 or later. This package also contains: • Flavio Gobber’s Elf2Coff converter. • The gcctest 1-9 files, by Volker Oth. Downloadable from www.avrfreaks.net. It is important that you try to use our package, as it contains all the correct additional files (.bat files, makefiles) that you need to complete this guide).
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 10 2006, 13:11
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(UniBomb @ Jul 10 2006, 15:39)  и я думаю что ты догадался почему Да и даже прямо написал это в одном из предыдущих постов. Цитата неужели никто не владеет алгоритмом высчитывания логаифма А собственно _алгоритм_ можете посмотреть именно в исходниках (например GCC) той самой библиотечной log() функции.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jul 10 2006, 19:43
|
Частый гость
 
Группа: Участник
Сообщений: 128
Регистрация: 7-06-06
Пользователь №: 17 825

|
Если не жалко держать таблицу из 256 значений, то можно так. Для определенности будем считать, что в вычислении ln(x), x это 16-бит целое число. (если х - дробное с фиксированной точкой, то результат просто смещается на -N*ln(2), где N - кол-во дробных бит) 1. Сдвигаем x влево до первой значащей единицы: X = x << K //К - число старших нулей// и вычисляем: Y1 = -K*ln(2) 2. Представляем: X = 256*A+B //т.е. A и B - старший и младший байты числа X// 3. Ищем по таблице: Y2 = TAB(A) где: TAB(A) = 8*ln(2)*ln(A) - таблица из 256 заранее расчитанных значений (здесь же можно учесть -N*ln(2) для дробного x: TAB(A) = 8*ln(2)*ln(A)-N*ln(2) ) 4. Вычисляем: Y3 = B/A 5. Собираем результат: ln(x) = Y1 + Y2 + Y3/256 "Теория метода": ln(x) = ln(X * 2**(-K)) = -K*ln(2) + ln(X) = Y1 + ln(X) ln(X) = ln(256*A+  = ln(256*A) + ln(1+B/(256*A)) = 8*ln(2)*ln(A) + ln(1+B/(256*A)) = = Y2 + ln(1+B/(256*A)) ln(1+B/(256*A)) ~ B/(256*A) = Y3/256 //с точностью не хуже 14 дробных бит!!!// Тут есть относительно трудоемкая операция B/А, но (если не ошибаюсь) например для вычисления 16-бит значения ln(x) при целом 16-бит x достаточно знать 4 старших бита B/A.
|
|
|
|
|
Jul 12 2006, 18:11
|
Частый гость
 
Группа: Участник
Сообщений: 128
Регистрация: 7-06-06
Пользователь №: 17 825

|
Цитата(UniBomb @ Jul 11 2006, 20:02)  vladv, надо будет запомнить, спасибо.... правда памяти у меня всего 512 байт... а ведь где то надо ещё и конфигурациоонные настройки сохранить... 512 байт - это памяти команд? Кстати, учитывая что после шага 1 старший бит аргумента будет всегда 1, размер таблицы можно сократить до 128 значений. Еще можно разменять размер таблицы на число допонительных делений. Например, для таблицы в 8 значений, надо будет сделать 4 деления (а также несколько сложений/вычитаний и сдвигов). Деления можно заменить еще одной таблицей такого-же размера и умножением. Если кому интересно - дайте знать.
|
|
|
|
|
Jul 15 2006, 11:55
|
Частый гость
 
Группа: Новичок
Сообщений: 173
Регистрация: 3-09-04
Из: Moscow
Пользователь №: 595

|
Способ, который описал vladv, фактически оптимизирован по скорости вычисления. Если же нужно сэкономить память (в ущерб скорости), можно воспользоваться вычислением "в лоб".
Логарифм - функция, очень хорошая в том смысле, что при разложении в ряд нет необходимости заботиться о сходимости в широких пределах (как правило, для синуса необходима сходимость от 0 до pi/2). Можно выбрать малый интервал от 1 до (1+eps), в котором ряд для логарифма (по ссылке в википедии) сходится с достаточной точностью вычислением малого количества членов. А дальше - умножая исходное число на некоторую целую степень (1+eps), можно попасть в выбранный интервал.
То есть, потребуется числа (1+eps) и ln(1+eps) вычислить заранее и хранить как константы, а в процессе вычислений: 1) Вычисляя целые степени числа (1+eps), найти такую целую степень N, которая максимально приблизится к исходному числу X (например, выполнять поиск N методом деления отрезка пополам) 2) Разделить X на (1+eps)^N, получив число Y из диапазона 1..(1+eps) 3) Вычислить сумму ряда ln(Y) Далее - вычисляем ln(X) = N*ln(1+eps) + ln(Y)
В памяти - никаких таблиц. Количество членов ряда и число eps выбираются исходя из требуемой точности и из соображений одинакового времени вычислений на первом и третьем шагах (чтобы минимизировать общее время вычислений), т.к. уменьшение eps увеличивает время выполнения первого шага и уменьшает время третьего.
Сообщение отредактировал CD_Eater - Jul 15 2006, 11:58
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|