Re: большая степень двойки
От: Кодт Россия  
Дата: 19.09.07 17:37
Оценка: 3 (1)
Здравствуйте, <Аноним>, Вы писали:

А>алгоритм без циклов для нахождения степени двойки, бОльшей (ну или равноq если число и есть степень двойки) данного числа, например


1) линейный поиск
unsigned f(unsigned const x)
{
    unsigned y = 1;
    while(y<x && y!=0) // обратите внимание на проверку нуля! мы можем нарваться на переполнение
        y <<= 1;
    return y;
}

2) двоичный поиск
unsigned f(unsigned const x)
{
    unsigned i=0, j=sizeof(unsigned)*CHAR_BIT; // ищем в интервале [i,j)
    while(i<j)
    {
        unsigned const m=(i+j)/2;
        unsigned const y=1<<m;
        
        if(x < y)
            j=m;
        else if(y < x)
            i=m+1;
        else
        {
            i=m;
            break;
        }
    }
    return 1<<i;
}

3) двоичный поиск, переосмысленный
unsigned f(unsigned const x, unsigned const bit = sizeof(unsigned)*CHAR_BIT/2)
{
    if(bit==0)
        return 1;
    else if(x < (1<<bit))
        return f(x, bit/2);
    else
        return f(x>>bit, bit/2)<<bit;
}

4) логарифмы
unsigned f(unsigned const x)
{
    return 1<<(unsigned)ceil(log(x)/log(2));
}
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re: большая степень двойки
От: e-Xecutor Россия  
Дата: 20.09.07 05:20
Оценка:
Здравствуйте, Аноним, Вы писали:

А>алгоритм без циклов для нахождения степени двойки, бОльшей (ну или равноq если число и есть степень двойки) данного числа, например

А>15 ==> 16
А>200 ==> 256
А>7923 ==> 8192

А lookup массивы разрешено использовать?
Re: большая степень двойки
От: vitalyk  
Дата: 20.09.07 09:51
Оценка: 1 (1)
Здравствуйте, <Аноним>, Вы писали:

А>алгоритм без циклов для нахождения степени двойки, бОльшей (ну или равноq если число и есть степень двойки) данного числа, например

А>15 ==> 16
А>200 ==> 256
А>7923 ==> 8192

Для IEEE'шных double (64 бита) и 32-битных unsigned int'ов <= 2^31 :

// Number of leading zeroes
int nlz( unsigned k ) 
{
    union 
    {
        unsigned asInt[2]; 
        double asDouble; 
    }; 
    
    asDouble = static_cast<double>( k ) + 0.5; 
    return 1054 - (asInt[1] >> 20); 
} 

unsigned top2( unsigned n )
{
  return 1 << ( 32 - nlz( n - 1 ) );
}


P.S. Все (c) Hacker's Delight
... << RSDN@Home 1.2.0 alpha rev. 746>>
Re: большая степень двойки
От: Checkist82  
Дата: 25.09.07 06:36
Оценка: :))
Здравствуйте, Аноним, Вы писали:

А>алгоритм без циклов для нахождения степени двойки, бОльшей (ну или равноq если число и есть степень двойки) данного числа, например

А>15 ==> 16
А>200 ==> 256
А>7923 ==> 8192
Не знаю, на сколько явными не должны быть циклы, но я б слепил что-нить подобное:
int func(int input_num)
{
char buf[100];
itoa(input_num,buf,2);
int length = strlen(buf);
output_num = 1;
output_num <<= length-1;
if (output_num < input_num)
{
output_num *= 2;
}
return output_num;
}
Железной рукой загоним человечество в счастье.
Re[2]: большая степень двойки
От: Checkist82  
Дата: 26.09.07 18:16
Оценка: +1
Здравствуйте, Checkist82, Вы писали:

C>Здравствуйте, Аноним, Вы писали:


Подумал спокойно — вывод, моё решение можно отправлять в КУ в раздел ещё один пример индусского кода
Железной рукой загоним человечество в счастье.
Re[3]: большая степень двойки
От: Erop Россия  
Дата: 26.09.07 20:28
Оценка:
Здравствуйте, Checkist82, Вы писали:

C>Подумал спокойно — вывод, моё решение можно отправлять в КУ в раздел ещё один пример индусского кода


Зато прикольно. Я думал это стёб такой
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: большая степень двойки
От: Checkist82  
Дата: 27.09.07 05:22
Оценка:
Здравствуйте, Erop, Вы писали:

E>Зато прикольно. Я думал это стёб такой


Спасибо, что так подумали — у меня бывает иногда, включаю тупого неожиданно сам для себя, а потом удивляюсь, как мне вообще такое в голову могло придти, вроде не курил ничего . Хотя в 1 случае из 10, такой "нестандартный" взгляд приводит к интересным результатам.
Железной рукой загоним человечество в счастье.
Re[3]: большая степень двойки
От: programmater  
Дата: 28.09.07 07:40
Оценка:
Здравствуйте, Вадим Никулин, Вы писали:

ВН>Здравствуйте, Les, Вы писали:


Les>>Здравствуйте, Аноним, Вы писали:


А>>>алгоритм без циклов для нахождения степени двойки, бОльшей (ну или равноq если число и есть степень двойки) данного числа, например

А>>>15 ==> 16
А>>>200 ==> 256
А>>>7923 ==> 8192

Les>>Для 32-разрядного:


Les>>Х |= X >> 1;

Les>>Х |= X >> 2;
Les>>Х |= X >> 4;
Les>>Х |= X >> 8;
Les>>Х |= X >> 16;
Les>>X++;

ВН>Для N-разрядного в любом случае можно цикл развернуть — будет без цикла.

ВН>А это — как раз развернутый цикл.
ВН>ЗЫЖ идея, конечно, хорошая
Идея хороша тем, что алгоритм имеет логарифмическую (от разрядности) сложноть, а не линейную, как первым приходит в голову. Единственная ошибка здесь, что X надо сначала уменьшить на 1, чтобы удовлетворить условию "ну или равноq если число и есть степень двойки". Если этого не сделать, то легко видеть, что, например, для 16 алгоритм выдаст ответ 32 вместо правильных 16.

ЗЫ. Все-таки лучше bsr-а ничего не придумаешь, так что кое-где ассемблер все же рулит . Интересно, существует ли код на C++, который заставит студию использовать bsr?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.