быстрое вычисление целочисленного логарифма

Aug 29, 2010 07:32

В любом современном языке программирования во время преобразование целого типа в натуральный происходит преобразование в формат IEEE 754, со всеми вытекающими отсюда обстоятельствами.

int i = 10; <- 4 байта в двоичном формате целого числа
float f = i; <- 4 байта в формате IEEE 754

Во время такого преобразования вычисляются мантисса и экспонента числа f, которые записываются в соответствии с правилами формата IEEE 754.

Экспонента которая записывается в места соответствующие маске 0x7F800000, уже сама по себе является логарифмом по основанию 2 от ближайшей степени двойки, меньшей преобразуемого числа. Или в другой интерпретации - это позиция старшего бита в преобразуемом числе.

В языке С++ операция по выделению экспоненты для объявленного целого числа lValue, с предварительным преобразованием типа выглядит следующим образом:
long lValue = 127;
float fValue = lValue;
long e = (((*(long*)(&fValue )) & 0x7F800000) >> 23) - 127;

Этот результат выполняется почти в 3 раза быстрее известного мне метода подсчета номера старшего единичного бита (47 мсек против 110 мсек при 10^7 итерациях). http://habrahabr.ru/blogs/algorithm/93172/

Для того чтобы использовать этот результат для вычисления не целого логарифма, можно использовать разложение в функции в ряд в точке 2^e до 2го, 3го или какого нужно члена...

К сожалению языки высокого уровня типа Java или Action Script не дают доступ к битам у переменных в формате IEEE754. Поэтому такая оптимизация возможна только на низкоуровневых языках типа Це++ или ассемблера.

танцы с бубном

Previous post Next post
Up