ПрограммированиеФорумОбщее

функции для работы с битами (3 стр)

Страницы: 1 2 3 4 Следующая »
#30
21:29, 13 июля 2009

OberMeister
Смотри base64 encoding.

#31
22:50, 13 июля 2009

dudenator
эээ... а причем тут это.

#32
23:45, 13 июля 2009

OberMeister
Там занимаются ровно тем же самым. Конвертируют переменные разной битовой длины друг в друга.

#33
0:14, 14 июля 2009

Я сделал у ся в аллокаторе вместо тучи булов , тучу бит масок..
Создал клас у которого 2 метода. Гет и Сет.
И каждый в 2-х варианта
1: устанавливает/возврашает 1 бит на позицыи Н
2: устанавливает/возврашает М битов с Н позицы Н

Если надо реализацыя могу поискать..

#34
3:05, 14 июля 2009

зачем что то изобретать, если с++ то есть bitset
http://www.cplusplus.com/reference/stl/bitset/

#35
8:38, 14 июля 2009

я, будучи студентом, реализоввывал такую же задачу (подсматривая в исходники какого то из архиваторов)
сорри за "много букв" :)

//bitio_f.h

#ifndef _BITIO_FILE_H_
#define _BITIO_FILE_H_

#include <stdio.h>
                   
#define READ_MODE  0
#define WRITE_MODE 1

class BitIOFile {
private:
  int           mode;
  FILE          *f;
  int           BitNumber;
  long long     BitBuffer; // 8 byte

public:
  BitIOFile();
   ~BitIOFile();

  int  create(char *filename);
  int  open(char *filename);

  void put(long b, unsigned char n = 1); // n - count, n <= 32
  long get(unsigned char n = 1);         // n - count, n <= 32

  void flush();
  void close();
};

#endif


//bitio_f.cpp

#include <assert.h>

#include "bitio_f.h"

static unsigned bitmask[] =
{
  0x00000000, 0x00000001, 0x00000003, 0x00000007,
  0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
  0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
  0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
  0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
  0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
  0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
  0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
  0xffffffff
};

BitIOFile::BitIOFile()
{
  assert(sizeof(long long) == 8);

  BitNumber = BitBuffer = 0;
  f = NULL;
}

BitIOFile::~BitIOFile()
{
  close();
}

int  BitIOFile::create(char *filename)
{
  if (f) close();
  mode = WRITE_MODE;
  f = fopen(filename, "wb+");
  BitNumber = BitBuffer = 0;
  if (!f) return 0;
  return 1;
}

int  BitIOFile::open(char *filename)
{
  if (f) close();
  mode = READ_MODE;
  f = fopen(filename, "rb");
  BitNumber = BitBuffer = 0;
  if (!f) return 0;
  return 1;
}

void BitIOFile::put(long b, unsigned char n /*=1*/)
{
  assert(n <= 32 && f);

  while(BitNumber >= 8)
  {
    fputc(BitBuffer & 0xff, f);
    BitNumber  -= 8;
    BitBuffer >>= 8;
  }

  BitBuffer |= (b & bitmask[n]) << BitNumber;
  BitNumber += n;
}

long BitIOFile::get(unsigned char n /*=1*/) 
{
  assert(n <= 32 && f);

  register long b;

  while(BitNumber < n)
  {
    BitBuffer |= (long)fgetc(f) << BitNumber;
    BitNumber += 8;
  }
  
  b = BitBuffer & bitmask[n];
  BitNumber  -= n;
  BitBuffer >>= n;

  return b;
}

void BitIOFile::flush()
{
    assert(f);
  if (mode == READ_MODE) return;
    while(BitNumber > 0)
    {
      fputc(BitBuffer & 0xff, f);
      BitNumber  -= 8;
      BitBuffer >>= 8;
    }
}

void BitIOFile::close()
{
  if (f)
  {
     flush();
     fclose(f);
     f = NULL;
  }
}

//test.cpp

#include <stdio.h>
#include "bitio_f.h"

int main()
{
  int i, j;
    BitIOFile f;

  //create & write
  f.create("test.bin");
  for (i = 0; i < 10; ++i)
    f.put(i, 12);
  f.close();


  //open & read
  f.open("test.bin");
  for (i = 0; i < 10; ++i)
  {
    j = f.get(12);
    printf("%d\n", j);
  }
  f.close();

  return 0;
}
#36
9:33, 14 июля 2009

Оператор ведь можно сделать как-то так:
bool& operator[](int index);?

Тогда вроде бы можно будет устанавливать значения? Или тут как со static_cast?

#37
11:33, 14 июля 2009

Если совсем нефиг делать можно нахимичить 1 хрень..

Создать клас который хранит индекс бита, указатель на битмаску и Бул
Потом приблизительно так

struct bitclass
{
  void* _ptr;
  uint _pos;
  bool status;
  bitclass(void* ptr,uint pos): _ptr(ptr), _pos(pos) {};
  ~bitclass() { *((long long*)_ptr) |= status==1?0x1:0 << pos; };
  bitclass& operator =(bool value) { status = value; return *this; };
};

bitclass& operator[](uint pos)
{
  // mask - our bitmask.. for ex. int;
  return bitclass(&mask,pos);
};

как оно работает!!!
конструктор - думаю все ясно!
деструктор - самое веселое, после ретурна в той строке кода где был вызов переменная будет сушиствовать и может менять значение, само пресвоение значения будет срабатівать именно в деструкторе!!!

Код написал только что на коленке.. на компил не провирял, но знаю что идея работает)

#38
12:13, 14 июля 2009

Сегодня утром написал то что нужно...

void bitwrite(short n,int numbit)
{
unsigned int byte,bit;

  if(n > (1<<numbit)) return;

  for(int i = 0; i < numbit; i++)
  {
  byte = (i+pos_write) / 8;
  bit = (i+pos_write) % 8;
  //printf("%i %i = %i\n",byte,bit,!!(n&(1<<i))); // debug
  buffer[byte] |= !!(n&(1<<i)) ? (1<<bit) : 0;
  }
 pos_write += numbit;
}

short bitread(int numbit)
{
unsigned int byte,bit;
short out = 0;

  for(int i = 0; i < numbit; i++)
  {
  byte = (i+pos_read) / 8;
  bit = (i+pos_read) % 8;
  out |= !!(buffer[byte]&(1<<bit)) ? (1<<i) : 0;
  }

pos_read += numbit;
return out;
}

Всем спасибо!

#39
13:13, 14 июля 2009

2OberMeister
видно тебе это для компресии
видел решения без извратов, и выглядят норм, но не знаю подойдет тебе или нет. Основанны на паттерне потока, ты кидаешь туда инт и колличество валидных байт, и так же достаешь. а внутри тупо длинный буфер, можно даже вектор int, чтобы память за тебя рулилась, и тупо сдвигами, но тут без произвольного доступа, именно записал, и считал, аккурат серелизация.

#40
13:28, 14 июля 2009

my.name
>видно тебе это для компресии
Именно. допустим мне нужна переменная с размером 512, придется взять short (16 бит) или же взять 9 бит.

>но не знаю подойдет тебе или нет.
Просто не хочу копать глубоко, может задумка и не оправдается.

#41
15:22, 14 июля 2009

Если тебе нужна просто переменная, то бери int, и не задумывайся даже про её размер, пока она одна никто и не заметит эти полтора байта экономии.
А если тебе надо упаковать стопицот записей в наименьший объём, тогда начинай морочить себе голову с битовыми полями и алгоритмами сжатия.

#42
16:02, 14 июля 2009

Просто напиши функцию, которая сожмет массив интов до желаемого размера (оставив от каждого элемента столько бит, сколько тебе хочется).
И еще напиши функцию для разжимания.
Вот и все.
Сложные классы, перегруженные операторы и имитация переменных с неродным количеством битов в байте - нахрен не надо.

#43
18:23, 14 июля 2009

kvakvs
Конишуа
Все уже решено!
При первых тестах все заработало с первого раза, обычно так не бывает :)

ЗЫ. Результат первых тестов: на максимальном качестве - сжатие в ~2 раза, опять же % сжатия зависит от сложности рисунка.

#44
0:48, 15 июля 2009

OberMeister
> ЗЫ. Результат первых тестов: на максимальном качестве - сжатие в ~2 раза, опять же % сжатия зависит от сложности рисунка.
Без указания типа рисунка нельзя ничего сказать, но если это принтскрин виндовских окошек или рыготня в Пеинте из нескольких нажатий, то это не результат :)

Страницы: 1 2 3 4 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.