как узнать номер n-го установленного (1) бита внутри long?
От: ilnar Россия  
Дата: 27.04.03 14:15
Оценка:
сабж.
как узнать номер n-го установленного (1) бита внутри long?
не ли какой-либо команды процессора или какой-нибудь код для С/С++
Re: как узнать номер n-го установленного (1) бита внутри lon
От: Baggy  
Дата: 27.04.03 14:31
Оценка: :)
Здравствуйте, ilnar, Вы писали:

I>сабж.

I>как узнать номер n-го установленного (1) бита внутри long?
I>не ли какой-либо команды процессора или какой-нибудь код для С/С++

я бы организовал цикл по маске выделения,
что то в духе

unsigned long temp = 0;

for (int i = 0; i< 32; i++)
{
    // проверяешь установлен ли i-й бит в 1...
    if ((your_long & temp) >> i) == 1)
    {
        // какая то обработка...
    }

    //переходим к след биту
    temp = temp << 1;
}
Re: как узнать номер n-го установленного (1) бита внутри lon
От: Кодт Россия  
Дата: 27.04.03 15:03
Оценка: -2
Здравствуйте, ilnar, Вы писали:

I>как узнать номер n-го установленного (1) бита внутри long?

I>не ли какой-либо команды процессора или какой-нибудь код для С/С++

Такой команды нет. Но написать функцию или макрос несложно.

за O(N)
int what_bit(unsigned long x)
{
  if(x==0) return -1; // no bits
  int c=0;
  while(!(x&1)) { x>>=1; ++c; }
  if(x!=1) return -2; // multiple bits
  return c;
}

За O(log N) — двоичный поиск: x<>2^16? x<>2^8? и так далее.
#define bit(n) (1<<(n))

int what_bit(unsigned long x)
{
  if(x == 0) return -1;
  if((x & (x-1)) != 0) return -2; // выставлено более 1 бита

#define test(n) if(x == bit(n)) return n; else if(x < bit(n))

  // 0..31
  test(16)
    // 0..15
    test(8)
      // 0..7
      test(4)
        // 0..3
        test(2)
          // 0..1
          test(1)
            return 0;
          else
            return -3; // ошибка! так не бывает.
        else
          return 3;
      else
        // 4..6
        test(5)
          return 4;
        else
          return 6;
    else
      // 9..15
      test(12)
        // 9..11
        test(10)
          return 9;
        else
          return 11;
      else
        // 13..15
        test(14);
          return 13;
        else
          return 15;
  else
    // 17..31
    test(24)
      // 17..23
      test(20)
        // 17..19
        test(18)
          return 17;
        else
          return 19;
      else
        // 21..23
        test(22)
          return 21;
        else
          return 23;
    else
      // 25..31
      test(28)
        // 25..27
        test(26)
          return 25;
        else
          return 27;
      else
        // 29..31
        test(30)
          return 29;
        else
          return 31;

#undef test
}
(=^.^=) Neko ... << RSDN@Home 1.0 beta 6a >>
Перекуём баги на фичи!
Re[2]: как узнать номер n-го установленного (1) бита внутри
От: MaximE Великобритания  
Дата: 27.04.03 16:29
Оценка:
Здравствуйте, Кодт, Вы писали:

К>за O(N)


[]

К>За O(log N) — двоичный поиск: x<>2^16? x<>2^8? и так далее.


[]

Я видел код (буквально пять строчек), который это делает без цикла за O(1). Вот только ссылку никак не могу найти
Re[3]: как узнать номер n-го установленного (1) бита внутри
От: Sergeem Израиль  
Дата: 28.04.03 07:43
Оценка: -1
Здравствуйте, MaximE, Вы писали:

ME>Я видел код (буквально пять строчек), который это делает без цикла за O(1). Вот только ссылку никак не могу найти


int what_bit(unsigned long x)
{
  if(x==0) return -1; // no bits
  if (x & (x-1)) return -2; // multiple bits

  return int(log(x)/log(2)); //  :shuffle: ;) 
}


Как бы логарифм по основанию два извлечь без плавающей точки и за О(1)?

Исправлена подсветка синтаксиса. -- ПК
Serge.

Hасколько проще была бы жизнь, если бы она была в исходниках.
Re[4]: как узнать номер n-го установленного (1) бита внутри
От: m.a.g. Мальта http://dottedmag.net/
Дата: 28.04.03 08:19
Оценка:
Здравствуйте, Sergeem, Вы писали:

S>Как бы логарифм по основанию два извлечь без плавающей точки и за О(1)?


Промелькнула такая мысль: поиграться с непереносимостью Можно преобразовать число в плавающую точку и поиграться с битами, ведь если наше число — степень двойки, то результат получится с мантиссой 1 и нужным порядком.
Re: как узнать номер n-го установленного (1) бита внутри lon
От: UgN  
Дата: 28.04.03 08:37
Оценка: 53 (4) -1
Здравствуйте, ilnar, Вы писали:

I>сабж.

I>как узнать номер n-го установленного (1) бита внутри long?
I>не ли какой-либо команды процессора или какой-нибудь код для С/С++



char GetBitPos( long n )
{
   char pos = 0;
   if(n & 0xFFFF0000) pos = 16, n >>= 16;
   if(n & 0x0000FF00) pos += 8, n >>= 8;
   if(n & 0x000000F0) pos += 4, n >>= 4;
   if(n & 0x0000000C) pos += 2, n >>= 2;
   if(n & 0x00000002) pos += 1;
   return pos;
};
Re: как узнать номер n-го установленного (1) бита внутри lon
От: Dmitry Kukushkin  
Дата: 28.04.03 08:49
Оценка: 38 (2)
Здравствуйте, ilnar, Вы писали:

I>сабж.

I>как узнать номер n-го установленного (1) бита внутри long?
I>не ли какой-либо команды процессора или какой-нибудь код для С/С++

Для i486+

int BitPos(long n)
{
    __asm
    {
      mov eax, n
      bsf eax, eax
    }
}
Re[2]: как узнать номер n-го установленного (1) бита внутри
От: WeCom Беларусь  
Дата: 28.04.03 08:58
Оценка:
Здравствуйте, UgN, Вы писали:


UgN>char GetBitPos( long n )


(риторический вопрос) А не дожен ли прототип функции быть таким? :

char GetBitPos( lond tested, long n )
Re[3]: как узнать номер n-го установленного (1) бита внутри
От: UgN  
Дата: 28.04.03 09:15
Оценка:
Здравствуйте, WeCom, Вы писали:

WC>
UgN>char GetBitPos( long n )
WC>

WC>(риторический вопрос) А не дожен ли прототип функции быть таким? :
WC>
WC>char GetBitPos( lond tested, long n )
WC>


Что это значит?
Re[4]: как узнать номер n-го установленного (1) бита внутри
От: WeCom Беларусь  
Дата: 28.04.03 09:20
Оценка:
Здравствуйте, UgN, Вы писали:

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


WC>
UgN>char GetBitPos( long n )
WC>

WC>(риторический вопрос) А не дожен ли прототип функции быть таким? :
WC>
WC>char GetBitPos( lond tested, long n )
WC>


UgN>Что это значит?

UgN>
Что сказано в сабже? — "как узнать номер n-го установленного (1) бита внутри long?"
Т.е. есть какое-то число (long). У него установлено несколько битов (в 1). Надо узнать номер (позицию) энного. Для n=1, задача в нахождении позиции самого правого единичного бита, для n=2 — позиции следующего единичного после самого правого, и т.д. А вы какую задачу решаете? — Найти позицию единственного единичного бита в long'е? Так это другая задача.
Re[3]: как узнать номер n-го установленного (1) бита внутри
От: Dmitry Kukushkin  
Дата: 28.04.03 09:21
Оценка:
Здравствуйте, WeCom, Вы писали:

WC>(риторический вопрос) А не дожен ли прототип функции быть таким? :


char GetBitPos( lond tested, long n )



Вообще то верно...
Вот, например, так ( для intel 80486+ ) :

char GetBitPos(long tested, long n)
{
  long i;
  char pos;
  for(i = 0; i < tested, n != 0; i++)
  {
    __asm
    {
       bsf eax, n
       btr n, eax
       mov pos, al
    }
  }
  return i == tested ? pos : -1;
}
Re[5]: как узнать номер n-го установленного (1) бита внутри
От: WeCom Беларусь  
Дата: 28.04.03 09:27
Оценка:
Здравствуйте, WeCom, Вы писали:

WC>А вы какую задачу решаете? — Найти позицию единственного единичного бита в long'е?

Тут я не прав, хотя в любом случае решаете какую-то другую (не из сабжа) задачу
Re[5]: как узнать номер n-го установленного (1) бита внутри
От: UgN  
Дата: 28.04.03 09:28
Оценка:
Здравствуйте, WeCom, Вы писали:

WC>Что сказано в сабже? — "как узнать номер n-го установленного (1) бита внутри long?"

WC>Т.е. есть какое-то число (long). У него установлено несколько битов (в 1). Надо узнать номер (позицию) энного. Для n=1, задача в нахождении позиции самого правого единичного бита, для n=2 — позиции следующего единичного после самого правого, и т.д. А вы какую задачу решаете? — Найти позицию единственного единичного бита в long'е? Так это другая задача.

Ooops!
Re[4]: как узнать номер n-го установленного (1) бита внутри
От: WeCom Беларусь  
Дата: 28.04.03 09:39
Оценка:
Здравствуйте, Dmitry Kukushkin, Вы писали:

DK>Вот, например, так ( для intel 80486+ ) :


DK>
DK>char GetBitPos(long tested, long n)
DK>{
DK>  long i;
DK>  char pos;
DK>  for(i = 0; i < tested, n != 0; i++)
DK>  {
DK>    __asm
DK>    {
DK>       bsf eax, n
DK>       btr n, eax
DK>       mov pos, al
DK>    }
DK>  }
DK>  return i == tested ? pos : -1;
DK>}
DK>

Неверно. Например, GetBitPos(0xF,3) должен вернуть 2, а возвращает -1. Возможно, n и tested перепутаны местами, но GetBitPos(3,0xF) также возвращает -1.
Re[5]: как узнать номер n-го установленного (1) бита внутри
От: Dmitry Kukushkin  
Дата: 28.04.03 09:52
Оценка: 21 (3) +1
Здравствуйте, WeCom, Вы писали:

WC>Неверно. Например, GetBitPos(0xF,3) должен вернуть 2, а возвращает -1. Возможно, n и tested перепутаны местами, но GetBitPos(3,0xF) также возвращает -1.



Извиняюсь...
Аргументы действительно перепутаны и в цикле там малек не то...
Ну вот — для ясности:

char GetBitPos(long data, long n)
{
  int i;
  char pos;
  for(i = 0; i < n && data != 0; i++)
  {
    __asm
    {
       bsf eax, data
       btr data, eax
       mov pos, al
    }
  }
  return i == n ? pos : -1;
}
Re[4]: как узнать номер n-го установленного (1) бита внутри
От: HeaveN Россия  
Дата: 28.04.03 11:14
Оценка:
Здравствуйте, Sergeem, Вы писали:

S>Как бы логарифм по основанию два извлечь без плавающей точки и за О(1)?


Не обязательно без плавающей точки, но думается так будет побыстрее:




int what_bit (long number)
{
  float f1;
  int f2;

  _asm
  {
    fld1
    fild dword ptr [number]
    fyl2x
    fst dword ptr [f1]
    fistp word ptr [f2]
  }
  
  if (f1==f2) return f2
  
  return -1;
}


Может, конечно, где и накосячил , но общая идея такая...
Нет такого закона, что человеку летать нельзя...
Re[3]: как узнать номер n-го установленного (1) бита внутри
От: MaximE Великобритания  
Дата: 28.04.03 11:19
Оценка: 14 (3)
Здравствуйте, MaximE, Вы писали:

ME>Я видел код (буквально пять строчек), который это делает без цикла за O(1). Вот только ссылку никак не могу найти


Оказалось, что не за O(1):

http://www.akzhan.midi.ru/devcorner/articles/bit-manipulation.html
Re[2]: как узнать номер n-го установленного (1) бита внутри
От: Andrew S Россия http://alchemy-lab.com
Дата: 28.04.03 11:56
Оценка:
А чем приведенный код поможет вопрошающему?
Насколько скудные познания ассемблера мне позовляют судить, в eax после выполнения данной последовательности команд будет помещен номер крайнего справа установленного в (1) бита (т.е. первого установленного бита, ежели такой есть). В вопросе же сказано — нужен номер n-го установленного бита. В этом случае я вижу 2 варианта — либо просто тупой перебор со свигом маски и счетчиком, либо использование более "быстрого" способа с BitPos, счетчиком и сдвигом результата.

I>сабж.

I>как узнать номер n-го установленного (1) бита внутри long?
I>не ли какой-либо команды процессора или какой-нибудь код для С/С++

DK>Для i486+


DK>
DK>int BitPos(long n)
DK>{
DK>    __asm
DK>    {
DK>      mov eax, n
DK>      bsf eax, eax
DK>    }
DK>}
DK>
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 28.04.03 12:17
Оценка:
Здравствуйте, Baggy, Вы писали:

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


I>сабж.

I>как узнать номер n-го установленного (1) бита внутри long?
I>не ли какой-либо команды процессора или какой-нибудь код для С/С++

B>я бы организовал цикл по маске выделения,

B>что то в духе

B>
B>unsigned long temp = 0;

B>for (int i = 0; i< 32; i++)
B>{
B>    // проверяешь установлен ли i-й бит в 1...
B>    if ((your_long & temp) >> i) == 1)
B>    {
B>        // какая то обработка...
B>    }

B>    //переходим к след биту
B>    temp = temp << 1;
B>}
B>


так очень долго и весь смысл кодирования потеряется
кстати, есть команда ror процессора (в кипе с циклом получим что надо), так быстрее будет, но хочется вот что-то хитрое сделать
Re[3]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 28.04.03 12:21
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Здравствуйте, Кодт, Вы писали:


К>за O(N)


ME>[]


К>За O(log N) — двоичный поиск: x<>2^16? x<>2^8? и так далее.


ME>[]


ME>Я видел код (буквально пять строчек), который это делает без цикла за O(1). Вот только ссылку никак не могу найти


а идею не помните?
Re[4]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 28.04.03 12:26
Оценка:
Здравствуйте, Sergeem, Вы писали:

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


ME>Я видел код (буквально пять строчек), который это делает без цикла за O(1). Вот только ссылку никак не могу найти


S>
S>int what_bit(unsigned long x)
S>{
S>  if(x==0) return -1; // no bits
S>  if (x & (x-1)) return -2; // multiple bits

S>  return int(log(x)/log(2)); //  :shuffle: ;) 
S>}
S>


S>Как бы логарифм по основанию два извлечь без плавающей точки и за О(1)?


может я не совсем правильно выразился, перефразирую вопрос:
есть некий long
в нем установлены в разных местах битики в 1, остальные 0.
в этой последовательности необходимо найти n-й по счету установленный в 1 бит. местоположение его конечно имеет номер не меньше n.
пример:
для 1001110010... и n=4, ответ будет = 6
Re[3]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 28.04.03 12:33
Оценка:
Здравствуйте, WeCom, Вы писали:

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



WC>
UgN>char GetBitPos( long n )
WC>


WC>(риторический вопрос) А не дожен ли прототип функции быть таким? :


WC>
WC>char GetBitPos( lond tested, long n )
WC>


именно должен, т.к. внутри long может быть несколько установленных битов, мне нужно узнать n-й по счету установленный, т.е. его позиция
Re[5]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 28.04.03 12:35
Оценка:
Здравствуйте, WeCom, Вы писали:

WC>Что сказано в сабже? — "как узнать номер n-го установленного (1) бита внутри long?"

WC>Т.е. есть какое-то число (long). У него установлено несколько битов (в 1). Надо узнать номер (позицию) энного. Для n=1, задача в нахождении позиции самого правого единичного бита, для n=2 — позиции следующего единичного после самого правого, и т.д. А вы какую задачу решаете? — Найти позицию единственного единичного бита в long'е? Так это другая задача.

МОЛОТЦА, я это и имел ввиду и эту задачу и надо решить, жеоательно, если руку приложат на ассемблере
Re[4]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 28.04.03 12:40
Оценка:
Здравствуйте, Dmitry Kukushkin, Вы писали:

DK>Вообще то верно...

DK>Вот, например, так ( для intel 80486+ ) :

DK>
DK>char GetBitPos(long tested, long n)
DK>{
DK>  long i;
DK>  char pos;
DK>  for(i = 0; i < tested, n != 0; i++)
DK>  {
DK>    __asm
DK>    {
DK>       bsf eax, n
DK>       btr n, eax
DK>       mov pos, al
DK>    }
DK>  }
DK>  return i == tested ? pos : -1;
DK>}
DK>


не совсем понял, а что в eax идет и условие для for — это с tested сравнивается или с n?
Re[6]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 28.04.03 13:21
Оценка:
Здравствуйте, Dmitry Kukushkin, Вы писали:

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


WC>Неверно. Например, GetBitPos(0xF,3) должен вернуть 2, а возвращает -1. Возможно, n и tested перепутаны местами, но GetBitPos(3,0xF) также возвращает -1.



DK>Извиняюсь...

DK>Аргументы действительно перепутаны и в цикле там малек не то...
DK>Ну вот — для ясности:

DK>
DK>char GetBitPos(long data, long n)
DK>{
DK>  int i;
DK>  char pos;
DK>  for(i = 0; i < n && data != 0; i++)
DK>  {
DK>    __asm
DK>    {
DK>       bsf eax, data
DK>       btr data, eax
DK>       mov pos, al
DK>    }
DK>  }
DK>  return i == n ? pos : -1;
DK>}
DK>


МОЛОТЦА — САМЫЙ ЛУЧШИЙ ОТВЕТ МАКСИМАЛЬНЫЙ БАЛ

позволил себе несколько изменить код (если верить TrueTime от Numega, работает намного быстрее)

char GetBitPos1(long data, long n)
{
    char i;
  char pos;
    __asm
    {
       mov ecx, n
m:
       bsf eax, data
       btr data, eax
       jz end
       mov pos, al
       loop m
end:
       cmp ecx, 0
       je m2
       mov pos, 0
m2:
    }
  
  return pos ;
}
Re: как узнать номер n-го установленного (1) бита внутри lon
От: Les Россия  
Дата: 29.04.03 15:07
Оценка: 24 (2)
Здравствуйте, ilnar, Вы писали:

I>сабж.

I>как узнать номер n-го установленного (1) бита внутри long?
I>не ли какой-либо команды процессора или какой-нибудь код для С/С++

#include "iostream.h"

//  ВАРИАНТ1
int GetBitPos( int arg, int n )
{
    //  Простой вариант. Сложность - n
    int pos = 0;
    int cnt;
    for( cnt =0; cnt<n && pos<32; pos++){
        cnt += (arg>>31) & 1;
        arg <<= 1;
    }
    if( cnt<n )
        return -1;
    else
        return pos;
}

//  ВАРИАНТ2
int GetBitPos2( unsigned int arg, int n )
{
    //  Базируется на алгоритме подсчета установленных битов в слове,
    //  было то ли в алгоритмах, то ли в этюднике
    unsigned int n1 = ((arg& 0xAAAAAAAA) >> 1 ) + (arg& 0x55555555);
    unsigned int n2 = ((n1 & 0xCCCCCCCC) >> 2 ) + (n1 & 0x33333333);
    unsigned int n3 = ((n2 & 0xF0F0F0F0) >> 4 ) + (n2 & 0x0F0F0F0F);
    unsigned int n4 = ((n3 & 0xFF00FF00) >> 8 ) + (n3 & 0x00FF00FF);
    unsigned int n5 = ((n4 & 0xFFFF0000) >> 16) + (n4 & 0x0000FFFF);

    //  n5 - общее кол-во установленных битов


    if (n5 < n)
        return -1;
    if (!n)
        return 0;
    
    //  Ищем спускаясь по двоичному дереву. Сложность - log(n)

    int pos;
    unsigned int mask = 0xFFFF0000;
    int leftHalf = (n4 & mask) >> 16;

    if ( n > leftHalf){            
        pos = 16;                   //  Вправо
        n -= leftHalf;
        mask >>= 16;
    }
    else{
        pos = 0;                    //  Влево
    }

    mask &= 0xFF00FF00;
    leftHalf = (n3 & mask) >> (32-pos-8);

    if ( n > leftHalf){            
        pos += 8;                   //  Вправо
        n -= leftHalf;
        mask >>= 8;
    }

    mask &= 0xF0F0F0F0;
    leftHalf = (n2 & mask) >> (32-pos-4);

    if ( n > leftHalf){            
        pos += 4;                   //  Вправо
        n -= leftHalf;
        mask >>= 4;
    }

    mask &= 0xCCCCCCCC;
    leftHalf = (n1 & mask) >> (32-pos-2);

    if ( n > leftHalf){            
        pos += 2;                   //  Вправо
        n -= leftHalf;
        mask >>= 2;
    }

    mask &= 0xAAAAAAAA;
    leftHalf = (arg & mask) >> (32-pos-1);

    if ( n > leftHalf){            
        pos += 1;                   //  Вправо
        n -= leftHalf;
        mask >>= 1;
    }
    return pos+1;
}

//  ТЕСТ
int main(int argc, char* argv[])
{
    printf("Hello World!\n");

    cout << GetBitPos ( 0, 0 ) << "\n";
    cout << GetBitPos ( 0xFF00FF00, 1 ) << "\n";
    cout << GetBitPos ( 0xFF00FF00, 3 ) << "\n";
    cout << GetBitPos ( 0xFF00FF00, 9 ) << "\n";
    cout << GetBitPos ( 0xFF00FF00, 20) << "\n";
    cout << GetBitPos2( 0, 0 ) << "\n";
    cout << GetBitPos2( 0xFF00FF00, 1 ) << "\n";
    cout << GetBitPos2( 0xFF00FF00, 3 ) << "\n";
    cout << GetBitPos2( 0xFF00FF00, 9 ) << "\n";
    cout << GetBitPos2( 0xFF00FF00, 20) << "\n";
    
    flush(cout);

    unsigned int i;
    int r=0;

    for(i=0;i<10000000;i++){
        r+=GetBitPos( i, i % 16);
    }

    cout << r << "\n";
    flush(cout);
    r = 0;

    for(i=0;i<10000000;i++){
        r+=GetBitPos2( i, i % 16);
    }

    cout << r << "\n";
    flush(cout);

    return 0;
}

Работает! Самое смешное, второй вариант действительно быстрее (int32, x86, vc60) % на 30. ilnar, с тебя пузырь! Вообще то, если использовать встроенную инструкцию поиска первого бита, будет конечно быстрее. Зато так переносимо. И соответствует форуму. И вообще круче.
Re[2]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 29.04.03 15:23
Оценка:
Здравствуйте, Les, Вы писали:

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

Les>Работает! Самое смешное, второй вариант действительно быстрее (int32, x86, vc60) % на 30. ilnar, с тебя пузырь! Вообще то, если использовать встроенную инструкцию поиска первого бита, будет конечно быстрее. Зато так переносимо. И соответствует форуму. И вообще круче.

а мне совсем не смешно от того, что операции С/С++ намного урезают операции процессора, иногда смотришь команды процессора и видишь, что то, что я пишу на С — на самом-то деле выполняется одной операцией процессора.

Соответствие форуму у ассемблера тоже есть по двум причинам:
— хотел получиь лаконичный ответ на С/С++
— ассемблерные вставки описаны в этих языках

кстати, gcc уже поддерживает формат записи ассемблера как у майкрасофта,
а переносимость на другие аппаратные платформы и не собираюсь
Re: как узнать номер n-го установленного (1) бита внутри lon
От: Artem_Sh  
Дата: 29.04.03 17:16
Оценка:
Здравствуйте, ilnar, Вы писали:

I>сабж.

I>как узнать номер n-го установленного (1) бита внутри long?
I>не ли какой-либо команды процессора или какой-нибудь код для С/С++
для этого есть шаблон std::bitset.
Re[3]: как узнать номер n-го установленного (1) бита внутри
От: Sergeem Израиль  
Дата: 30.04.03 08:32
Оценка:
Здравствуйте, ilnar, Вы писали:

...

I>кстати, gcc уже поддерживает формат записи ассемблера как у майкрасофта,

I>а переносимость на другие аппаратные платформы и не собираюсь

не зарекайтесь!
завтра (вспомните закон Мура) выйдет новый супер-пупер 137-битный процессор
у которого родной istruction set будет в 10 раз быстрее чем ваши х86 ассемблерные
вставки. Что, будете каждый раз код переписывать?
Serge.

Hасколько проще была бы жизнь, если бы она была в исходниках.
Re[4]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 30.04.03 11:02
Оценка:
Здравствуйте, Sergeem, Вы писали:

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


S>...


I>кстати, gcc уже поддерживает формат записи ассемблера как у майкрасофта,

I>а переносимость на другие аппаратные платформы и не собираюсь

S>не зарекайтесь!

S>завтра (вспомните закон Мура) выйдет новый супер-пупер 137-битный процессор
S>у которого родной istruction set будет в 10 раз быстрее чем ваши х86 ассемблерные
S>вставки. Что, будете каждый раз код переписывать?

скжау 2 вещи:
1. языки высокого уровня всегда урезают возможности процессора для реализации какой-либо операции.
2. я найду время переписать код в 10 строк, зато программа будет быстрее намного работать
Re: как узнать номер n-го установленного (1) бита внутри lon
От: impaler  
Дата: 30.04.03 11:55
Оценка: :)))
Здравствуйте, ilnar, Вы писали:

I>сабж.

I>как узнать номер n-го установленного (1) бита внутри long?
I>не ли какой-либо команды процессора или какой-нибудь код для С/С++


Так вот, надо создать базу данных всех чисел типа long где для каждого бита каждого числа будет храниться значение, указывающее, установлен он в 1 или в 0. Теперь при необходимости можно выполнить SQL-запрос и получить полную информацию о каждом бите нужного числа
Re[2]: как узнать номер n-го установленного (1) бита внутри
От: Аноним  
Дата: 30.04.03 11:58
Оценка:
Здравствуйте, impaler, Вы писали:

I>Так вот, надо создать базу данных всех чисел типа long где для каждого бита каждого числа будет храниться значение, указывающее, установлен он в 1 или в 0. Теперь при необходимости можно выполнить SQL-запрос и получить полную информацию о каждом бите нужного числа


Что ж, это максимально гибко. А при необходимости битовое представление чисел можно будет даже и менять!
Re[2]: как узнать номер n-го установленного (1) бита внутри
От: Юнусов Булат Россия  
Дата: 30.04.03 17:31
Оценка:
Здравствуйте, Artem_Sh, Вы писали:

A_S>для этого есть шаблон std::bitset.


Согласен, правда boost::dynamic_bitset удобнее (размер в рантайме задавать можно)
Re[3]: как узнать номер n-го установленного (1) бита внутри
От: skyline Россия  
Дата: 02.05.03 08:26
Оценка: 9 (1)
Могу предложить еще один вариант.
typedef struct __My_bitset
{
unsigned f_0:1 ;
unsigned f_1:1 ;
unsigned f_2:1 ;
unsigned f_3:1 ;
unsigned f_4:1 ;
unsigned f_5:1 ;
unsigned f_6:1 ;
unsigned f_7:1 ;
unsigned f_8:1 ;
unsigned f_9:1 ;
unsigned f_10:1 ;
unsigned f_11:1 ;
unsigned f_12:1 ;
unsigned f_13:1 ;
unsigned f_14:1 ;
unsigned f_15:1 ;
unsigned f_16:1 ;
unsigned f_17:1 ;
unsigned f_18:1 ;
unsigned f_19:1 ;
unsigned f_20:1 ;
unsigned f_21:1 ;
unsigned f_22:1 ;
unsigned f_23:1 ;
unsigned f_24:1 ;
unsigned f_25:1 ;
unsigned f_26:1 ;
unsigned f_27:1 ;
unsigned f_28:1 ;
unsigned f_29:1 ;
unsigned f_30:1 ;
unsigned f_31:1 ;
} My_bitset ;

union My_B2L
{
long f_L ;
My_bitset f_bits ;
};

и копируй в первое поле long, получишь во втором битовый массив.

Кстати, что за зверь boost::dynamic_bitset ?
If the milk turns out to be sour,
I ain't the kind of pussy to drink it
Re[4]: как узнать номер n-го установленного (1) бита внутри
От: MaximE Великобритания  
Дата: 02.05.03 09:58
Оценка:
Здравствуйте, skyline, Вы писали:

S>Кстати, что за зверь boost::dynamic_bitset ?
Re[4]: как узнать номер n-го установленного (1) бита внутри
От: MaximE Великобритания  
Дата: 02.05.03 09:58
Оценка:
Здравствуйте, skyline, Вы писали:

S>Кстати, что за зверь boost::dynamic_bitset ?


Description
The dynamic_bitset class represents a set of bits. It provides accesses to the value of individual bits via an operator[] and provides all of the bitwise operators that one can apply to builtin integers, such as operator& and operator<<. The number of bits in the set is specified at runtime via a parameter to the constructor of the dynamic_bitset.

The dynamic_bitset class is nearly identical to the std::bitset class. The difference is that the size of the dynamic_bitset (the number of bits) is specified at run-time during the construction of a dynamic_bitset object, whereas the size of a std::bitset is specified at compile-time through an integer template parameter.

The main problem that dynamic_bitset is designed to solve is that of representing a subset of a finite set. Each bit represents whether an element of the finite set is in the subset or not. As such the bitwise operations of dynamic_bitset, such as operator& and operator|, correspond to set operations, such as intersection and union.

Re[5]: как узнать номер n-го установленного (1) бита внутри
От: skyline Россия  
Дата: 02.05.03 11:46
Оценка:
Здравствуйте, MaximE, Вы писали:

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


S>Кстати, что за зверь boost::dynamic_bitset ?


Я хотел спросить, это что: приблуда к C или приблуда к какому-то компилятору — а то у меня в MSDN нет ничего на эту тему. Судя по описанию, это неплохой механизм.
If the milk turns out to be sour,
I ain't the kind of pussy to drink it
Re[6]: как узнать номер n-го установленного (1) бита внутри
От: LCR Россия lj://_lcr_
Дата: 02.05.03 13:44
Оценка:
Здравствуйте, skyline, Вы писали:

S>Я хотел спросить, это что: приблуда к C или приблуда к какому-то компилятору ...


Это просто библиотека классов (см на sourceforge).
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[6]: как узнать номер n-го установленного (1) бита внутри
От: WFrag США  
Дата: 02.05.03 13:52
Оценка:
Здравствуйте, skyline, Вы писали:

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


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


S>>Кстати, что за зверь boost::dynamic_bitset ?


S>Я хотел спросить, это что: приблуда к C или приблуда к какому-то компилятору — а то у меня в MSDN нет ничего на эту тему. Судя по описанию, это неплохой механизм.


Это набор всяких разных дополнительных библиотек к C++, обладает довольно богатыми возможностями (кстати, может частично войдет в будущий стандарт STL).

Смотри тут: www.boost.org
... << RSDN@Home 1.0 beta 6a >>
Re[7]: как узнать номер n-го установленного (1) бита внутри
От: MaximE Великобритания  
Дата: 02.05.03 17:38
Оценка:
Здравствуйте, LCR, Вы писали:

LCR> Это просто библиотека классов (см на sourceforge).


совсем не просто
Re[8]: как узнать номер n-го установленного (1) бита внутри
От: LCR Россия lj://_lcr_
Дата: 03.05.03 06:27
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>совсем не просто


А если глянуть реализацию, то это даже сложно
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[2]: как узнать номер n-го установленного (1) бита внутри
От: _Dmitry_  
Дата: 21.04.04 07:38
Оценка:
Здравствуйте, UgN, Вы писали:

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


I>>сабж.

I>>как узнать номер n-го установленного (1) бита внутри long?
I>>не ли какой-либо команды процессора или какой-нибудь код для С/С++


UgN>

UgN>char GetBitPos( long n )
UgN>{
UgN>   char pos = 0;
UgN>   if(n & 0xFFFF0000) pos = 16, n >>= 16;
UgN>   if(n & 0x0000FF00) pos += 8, n >>= 8;
UgN>   if(n & 0x000000F0) pos += 4, n >>= 4;
UgN>   if(n & 0x0000000C) pos += 2, n >>= 2;
UgN>   if(n & 0x00000002) pos += 1;
UgN>   return pos;
UgN>};
UgN>
Re: как узнать номер n-го установленного (1) бита внутри lon
От: LaptevVV Россия  
Дата: 21.04.04 09:50
Оценка:
Здравствуйте, ilnar, Вы писали:

I>сабж.

I>как узнать номер n-го установленного (1) бита внутри long?
I>не ли какой-либо команды процессора или какой-нибудь код для С/С++
Если еще интересует — в систему команд входит ряд команд Bit Test
BT, BTS, BTC, BTR — то что доктор прописал!
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 21.04.04 09:52
Оценка:
Здравствуйте, LaptevVV, Вы писали:

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


I>>сабж.

I>>как узнать номер n-го установленного (1) бита внутри long?
I>>не ли какой-либо команды процессора или какой-нибудь код для С/С++
LVV>Если еще интересует — в систему команд входит ряд команд Bit Test
LVV>BT, BTS, BTC, BTR — то что доктор прописал!

а как их использовать? код можно?
Re[3]: как узнать номер n-го установленного (1) бита внутри
От: LaptevVV Россия  
Дата: 21.04.04 10:03
Оценка:
Здравствуйте, ilnar, Вы писали:

I>>>как узнать номер n-го установленного (1) бита внутри long?

I>>>не ли какой-либо команды процессора или какой-нибудь код для С/С++
LVV>>Если еще интересует — в систему команд входит ряд команд Bit Test
LVV>>BT, BTS, BTC, BTR — то что доктор прописал!

I>а как их использовать? код можно?


bt ax,5         ;проверить значение 5-го бита - переносит бит в cf
;
mov ax, 10
bts pole, ax     ; проверить и установить 10-й бит в pole

Юолее подробно надо справочник по ассемблеру поднимать.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: как узнать номер n-го установленного (1) бита внутри lon
От: MShura  
Дата: 21.04.04 10:19
Оценка: 1 (1) +1
Здравствуйте, ilnar, Вы писали:

I>сабж.

I>как узнать номер n-го установленного (1) бита внутри long?
I>не ли какой-либо команды процессора или какой-нибудь код для С/С++

Не знаю писали здесь или нет, но вот как делаю я.
Расчитывается LookUpTabel[256].
Анализ содержимого long сводится к анализу четырех значений LookUpTable, индексом которой служит значение первого,второго,третьего,четвертого байтов из long.
В итоге обычно за можно обойтись вообще без циклов.
Re[2]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 21.04.04 10:23
Оценка:
Здравствуйте, MShura, Вы писали:

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


I>>сабж.

I>>как узнать номер n-го установленного (1) бита внутри long?
I>>не ли какой-либо команды процессора или какой-нибудь код для С/С++

MS>Не знаю писали здесь или нет, но вот как делаю я.

MS>Расчитывается LookUpTabel[256].
MS>Анализ содержимого long сводится к анализу четырех значений LookUpTable, индексом которой служит значение первого,второго,третьего,четвертого байтов из long.
MS>В итоге обычно за можно обойтись вообще без циклов.

плохо что обращение к памяти долго будет наверно, это критический момент, и еще, у меня массив long будет, как один непрерывный поток битов.
Re[3]: как узнать номер n-го установленного (1) бита внутри
От: MShura  
Дата: 21.04.04 10:39
Оценка:
Здравствуйте, ilnar, Вы писали:

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


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


I>>>сабж.

I>>>как узнать номер n-го установленного (1) бита внутри long?
I>>>не ли какой-либо команды процессора или какой-нибудь код для С/С++

MS>>Не знаю писали здесь или нет, но вот как делаю я.

MS>>Расчитывается LookUpTabel[256].
MS>>Анализ содержимого long сводится к анализу четырех значений LookUpTable, индексом которой служит значение первого,второго,третьего,четвертого байтов из long.
MS>>В итоге обычно за можно обойтись вообще без циклов.

I>плохо что обращение к памяти долго будет наверно, это критический момент, и еще, у меня массив long будет, как один непрерывный поток битов.


Такие алгоритмы я использую в своей файловой системе для поиска свободных кластеров.
Такой-же алгоритм, как оказалось, использует MS в коде NTFS для работы с битмапом занятых кластеров.

Вообще-то выбор алгоритма существенно зависит от цены jmp.
Например на DSP от Texas Instruments эта цена достаточно большая.
Если писать на asm то получишь непереносимый код, поскольку asm для каждого компилятора обычно имеет свои особенности.
Например для Watcom/GCC/MSVC синтаксис абсолютно разный.
Re[4]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 21.04.04 10:56
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Вообще-то выбор алгоритма существенно зависит от цены jmp.

MS>Например на DSP от Texas Instruments эта цена достаточно большая.
MS>Если писать на asm то получишь непереносимый код, поскольку asm для каждого компилятора обычно имеет свои особенности.
MS>Например для Watcom/GCC/MSVC синтаксис абсолютно разный.

а вот в в переводе из MSVC в GCC вид ассемблер я уж переведу быстро
Re: как узнать номер n-го установленного (1) бита внутри lon
От: avbochagov Россия  
Дата: 21.04.04 11:22
Оценка:
Здравствуйте, ilnar, Вы писали:

I>сабж.

I>как узнать номер n-го установленного (1) бита внутри long?
I>не ли какой-либо команды процессора или какой-нибудь код для С/С++

А почему так нельзя?

struct BITS
{
    unsigned b0:1;
    unsigned b1:1;
    unsigned b2:1;
    unsigned b3:1;
    unsigned b4:1;
    unsigned b5:1;
    unsigned b6:1;
    unsigned b7:1;
    unsigned b8:1;
    unsigned b9:1;
    unsigned b10:1;
    unsigned b11:1;
    unsigned b12:1;
    unsigned b13:1;
    unsigned b14:1;
    unsigned b15:1;
    unsigned b16:1;
    unsigned b17:1;
    unsigned b18:1;
    unsigned b19:1;
    unsigned b20:1;
    unsigned b21:1;
    unsigned b22:1;
    unsigned b23:1;
    unsigned b24:1;
    unsigned b25:1;
    unsigned b26:1;
    unsigned b27:1;
    unsigned b28:1;
    unsigned b29:1;
    unsigned b30:1;
    unsigned b31:1;
};

int main(int argc, char* argv[])
{
    long z = 8192;
    BITS* p = (BITS*)&z;
    return 0;
}


Остается только проверить
    if( p->b13 )
    {
        doSomeThing();
    }
... << RSDN@Home 1.1.3 stable >>
Re[2]: как узнать номер n-го установленного (1) бита внутри
От: ilnar Россия  
Дата: 21.04.04 11:26
Оценка:
Здравствуйте, avbochagov, Вы писали:

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


I>>сабж.

I>>как узнать номер n-го установленного (1) бита внутри long?
I>>не ли какой-либо команды процессора или какой-нибудь код для С/С++

A>А почему так нельзя?


задача в другом, есть long, допустим для примера 100110001010010001
нужно найти номер 4-го установленного в 1 бита, ответ: 9 (слева)
Re[3]: как узнать номер n-го установленного (1) бита внутри
От: Аноним  
Дата: 21.04.04 11:54
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Здравствуйте, Кодт, Вы писали:


К>>за O(N)


ME>[]


К>>За O(log N) — двоичный поиск: x<>2^16? x<>2^8? и так далее.


ME>[]


ME>Я видел код (буквально пять строчек), который это делает без цикла за O(1). Вот только ссылку никак не могу найти


а разве в "Алгоритмические трюки для программистов" этого нет?
Re[4]: как узнать номер n-го установленного (1) бита внутри
От: MaximE Великобритания  
Дата: 21.04.04 17:42
Оценка:
> ME>Я видел код (буквально пять строчек), который это делает без цикла за O(1). Вот только ссылку никак не могу найти
>
> а разве в "Алгоритмические трюки для программистов" этого нет?

Есть.

Но когда писался тот постинг я книжки не читал

--
Maxim Egorushkin
MetaCommunications Engineering
http://www.meta-comm.com/engineering/
Posted via RSDN NNTP Server 1.8 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.