Про натуральный логарифм

 

Есть ли у кого исходный код функции вычисления натурального логарифма с заданной точностью?

Пусть, хотя бы общий алгортм, но чтобы работала быстрее, чем встроенная функция MathLog() в mql4.

Спасибо!

 



Можно попользоваться Яндексом.

 
atom-dim:

Есть ли у кого исходный код функции вычисления натурального логарифма с заданной точностью?

Пусть, хотя бы общий алгортм, но чтобы работала быстрее, чем встроенная функция MathLog() в mql4.

Спасибо!

Откуда же код, если задача еще не поставлена. Глубоко сомневаюсь, что в MathLog() имеется какой-либо алгоритм, кроме, разве что, проверки аргумента на положителность. Уверен, что никакого кода там нет, есть лишь вызов аппаратно реализованной функции сопроцессора (FPU). В свое время проверял погрешности вычисления таких функций, так они совпали с погрешностью представления чисел в самом FPU. Это 10-байтные числа с плавающей точкой. Сложилось ощущение, что в отсутствие доминирования чьих-либо требований по точности создатели сопроцессоров реализовали максимум того, что могут передать наружу как результат.

Тип Размер типа, байт Размер мантиссы, бит Размер экспоненты, бит
Single 4 23 8
Double 8 52 11
Extended 10 64 15

О скорости выполнения вычислений в FPU по сравнению с программным кодом могу судить лишь по одному примеру, который в свое время был исследован для собственных нужд. В i387 появилась команда вычисления синуса и косинуса (сразу обоих). По сравнению с программным вариантом оказалось быстрее в 6 раз, 3-4 мс вместо 22 мс (тактовые частоты i386 были 12—40 МГц).

Среди многих способов вычислений логарифмов часто встречаются такие, что свою погрешность они не контролируют. Не зная, о каких допустимых погрешностях и скоростях идет речь, предложить подходящий вариант сложно.

Поскольку управление точностью необходимо, мне пришло в голову решать вопрос как задачу Коши для обыкновенного дифуравнения, где таких методов навалом, от метода Эйлера (первого порядка) до Рунге-Кутта четвертого порядка точности; или, что то же самое, прямым численным интегрированием 1/x от x=1 до нужной точки y: ln(y) = ln(1) + интеграл от 1/x в пределах от 1 до y. Однако работу с контролем точности при численном интегрировании придется делать заново, по специфике задачи.

Можно сделать и таблицу значений с кусочно-линейной (или поточнее) интерполяцией. Ведь хватало же нам когда-то таблиц Брадиса. Все зависит от требований по точности и скорости. Кстати, важно, как должна оцениваться погрешность: надежно сверху с запасом или достаточно порядковой оценки.

 
Vlad143:

Откуда же код, если задача еще не поставлена. Глубоко сомневаюсь, что в MathLog() имеется какой-либо алгоритм, кроме, разве что, проверки аргумента на положителность. Уверен, что никакого кода там нет, есть лишь вызов аппаратно реализованной функции сопроцессора (FPU). В свое время проверял погрешности вычисления таких функций, так они совпали с погрешностью представления чисел в самом FPU. Это 10-байтные числа с плавающей точкой. Сложилось ощущение, что в отсутствие доминирования чьих-либо требований по точности создатели сопроцессоров реализовали максимум того, что могут передать наружу как результат.

Тип Размер типа, байт Размер мантиссы, бит Размер экспоненты, бит
Single 4 23 8
Double 8 52 11
Extended 10 64 15

О скорости выполнения вычислений в FPU по сравнению с программным кодом могу судить лишь по одному примеру, который в свое время был исследован для собственных нужд. В i387 появилась команда вычисления синуса и косинуса (сразу обоих). По сравнению с программным вариантом оказалось быстрее в 6 раз, 3-4 мс вместо 22 мс (тактовые частоты i386 были 12—40 МГц).

Среди многих способов вычислений логарифмов часто встречаются такие, что свою погрешность они не контролируют. Не зная, о каких допустимых погрешностях и скоростях идет речь, предложить подходящий вариант сложно.

Поскольку управление точностью необходимо, мне пришло в голову решать вопрос как задачу Коши для обыкновенного дифуравнения, где таких методов навалом, от метода Эйлера (первого порядка) до Рунге-Кутта четвертого порядка точности; или, что то же самое, прямым численным интегрированием 1/x от x=1 до нужной точки y: ln(y) = ln(1) + интеграл от 1/x в пределах от 1 до y. Однако работу с контролем точности при численном интегрировании придется делать заново, по специфике задачи.

Можно сделать и таблицу значений с кусочно-линейной (или поточнее) интерполяцией. Ведь хватало же нам когда-то таблиц Брадиса. Все зависит от требований по точности и скорости. Кстати, важно, как должна оцениваться погрешность: надежно сверху с запасом или достаточно порядковой оценки.

Спасибо, за подробный ответ.

Округление необходимо до 0,00001. Работа с целыми числами от 1 до 1000

Скорее всего, просто составлю таблицу и буду осуществлять поиск.

Думаю, перебор по массиву будет быстрее, чем вычисление самой функции.

 
atom-dim:

Думаю, перебор по массиву будет быстрее, чем вычисление самой функции.

Тогда уж просто через индексацию массива. Это вообще быстро. В крайнем случае через switch, он чуть медленнее, чем прямая индексация, но немного гибче.
 
atom-dim:

Спасибо, за подробный ответ.

Округление необходимо до 0,00001. Работа с целыми числами от 1 до 1000

Скорее всего, просто составлю таблицу и буду осуществлять поиск.

Думаю, перебор по массиву будет быстрее, чем вычисление самой функции.

Так Вам требуется только одна тысяча значений в заранее известных точках? Зачем округлять, не понял. На первом запуске программы подсчитать все эти значения в тип double (16-17 значащих цифр) и все, не пожалейте 8 Кб памяти для массива этих значений. Время вычисления сведется к времени адресации в массиве. Если жаль 8 Кб, помещайте в 4-байтные вещественные числа, хватит 4 Кб. При чем здесь перебор, если нужные аргументы из набора целых от 1 до 1000?

Вообще-то, искренне не могу понять задачу.