нет, не видел. дадите ссылку посмотрю))
нет, не видел. дадите ссылку посмотрю))
начинающий профессионал
Вторая версия макроса "Двоичный логарифм", с использованием цикла, но и более точным ответом.
На этот раз мгновенный ответ с точностью до 0.5, повышая точность с каждым тактом ПР на один двоичный разряд
(точность 1/2ⁿ, где n-номер такта после изменения начального значения)
PS на 20ом такте достигается максимально возможная точность (1/2^20 ~ 1/10^6)
PPS по просьбам читателей, все связи в схеме абсолютно читаемы... (простите за тавтологию)
Последний раз редактировалось AI!; 07.06.2016 в 22:47.
начинающий профессионал
Тишина... Видимо у всех просто нет словДа уж, дружище, твоему усердию можно только позавидовать.
А давайте я вопрос задам?
Почему первые биты определяются пачками (через CD32), а остальные по одному?
В чём смысл получения битов по одному, если есть логарифмирующий блок?
Разе не получается вообще все биты через CD32 получать?
Образно: получили первые 32, поделили на 2CD32, умножили на 232, снова вызываем CD32.
И не придётся ждать 20 тактов.
Подумал...
В новой версии всё так же как и в первой, т.е. работает мгновенно, во всех допустимых значениях от 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)
Последний раз редактировалось AI!; 12.06.2016 в 01:25.
начинающий профессионал
О, здорово. Я правильно понимаю, что последней 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 на ряд (из двух элементов), то получится точный ответ:
Отсюда вывод: если на последнюю цепочку подаваемые значения невелики (близки к 1), то нужно заменять её на 2*(y+y**3/3)/Math.log(2)Код: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
Последний раз редактировалось Владимир Ситников; 12.06.2016 в 23:42.
я же сказал - точность до 1/256 (~0,004), правда забыл уточнить, что округление всегда в меньшую сторону (по модулю)
откуда ваша формула? можно ссылку?
PS тем временем сделал вариант с 4мя итерациями, получается точность 1/8192,
так же добавил выходы с ln(x) и lg(x), с учётом понижающего коэффициента, точность получается 1e-4
Последний раз редактировалось AI!; 13.06.2016 в 00:00.
начинающий профессионал
Это понятно. Я про то, что для близких к 1 значений можно вместо CD32 использовать ряд и тем самым повысить точность.
7-е сообщение в этой теме, 1-ая ссылка.
Могу повторить: https://ru.wikipedia.org/wiki/%D0%9B....D1.8F.D0.B4_2
Последний раз редактировалось Владимир Ситников; 13.06.2016 в 00:09.