
Сообщение от
AI!
Подумал...
В новой версии всё так же как и в первой, т.е. работает мгновенно, во всех допустимых значениях от 0 до 3,4E+38, и точность до 1/256.
Основное отличие - за счёт использования только CD32 получается всего 3 итерации (развёрнутых в линию, отсюда и мгновенность),
вместо 11 в первой публичной версии макроса (или 15, если бы CD32 вообще не использовался)
PS напомню: lb(x) - Двоичный логарифм
ln(x)=lb(x)/lb(e)=ln(2)*lb(x) = 0,693147*lb(x)
lg(x)=lb(x)/lb(10)=lg(2)*lb(x) = 0,30103*lb(x)
О, здорово. Я правильно понимаю, что последней CD32(POW(x, 256))/256 цепочке на вход всегда подаются данные в диапазоне 0,9...1,1?
Тогда можно повысить точность до 1.4e-4 == 1/6900, если использовать приближение lb(x) = 2*(x-1)/(x+1) / ln(2) вместо последней цепочки CD(POW)
Если взять ещё один член 2*((x-1)/(x+1) + ((x-1)/(x+1))3/3) / ln(2), то точность будет почти до 1e-7.
Вот пример такого (! на картинке два члена ряда не встроены в исходную формулу специально, чтобы сравнивать): lb2_3.png
lb(1.01) == 0.014355292977070055
Вариант с тремя CD32 выдаёт 1.2e-2
Если заменить последний CD32 на ряд (из двух элементов), то получится точный ответ:
Код:
irb(main):009:0> x=1.01
=> 1.01
irb(main):010:0> y=(x-1)/(x+1)
=> 0.004975124378109458
irb(main):012:0> Math.log(1.01, 2)
=> 0.014355292977070055
irb(main):013:0> 2*(y+y**3/3)/Math.log(2)
=> 0.014355292975311074
Отсюда вывод: если на последнюю цепочку подаваемые значения невелики (близки к 1), то нужно заменять её на 2*(y+y**3/3)/Math.log(2)