Ультра быстрый способ объединения байтовых значений - PullRequest
4 голосов
/ 26 июля 2011

Учитывая 3 разных байта, таких как, скажем, x = 64, y = 90, z = 240. Я хочу объединить их, скажем, в строку типа 6490240. Было бы замечательно, если бы это сработало, но это не так:

 string xx = (string)x + (string)y + (string)z;

Я работаю в C ++ и согласился бы на конкатенацию байтов в виде 24-битной строки с использованием их 8-битных представлений.

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

Большое спасибо за вашу помощь

Чтобы уточнить, причина, по которой я особенно обращаю внимание на использование 3 байтов, заключается в том, что исходные данные относятся к значениям RGB, которые считываются через указатели и хранятся, конечно, как байты.в памяти.

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

Ответы [ 5 ]

10 голосов
/ 26 июля 2011

Самый простой способ превратить числа в строку - это использовать ostringstream

#include <sstream>
#include <string>
std::ostringstream os;
os << x << y << z;
std::string str = os.str();   // 6490240

Вы можете даже использовать манипуляторы, чтобы сделать это в шестнадцатеричном или восьмеричном виде:

os << std::hex << x << y << z;

Обновление

Поскольку вы уточнили, что вы действительно хотите сделать, я обновил свой ответ. Вы хотите принять значения RGB за три байта и каким-то образом использовать их в качестве ключа. Это лучше всего сделать с длинным int, а не в виде строки. Вы все еще можете легко преобразовать int в строку для печати на экране.

unsigned long rgb = 0;
byte* b = reinterpret_cast<byte*>(&rgb);
b[0] = x;
b[1] = y;
b[2] = z;
// rgb is now the bytes { 0, x, y, z }

Тогда вы можете использовать long int rgb в качестве ключа, очень эффективно. Всякий раз, когда вы хотите распечатать его, вы можете сделать это:

std::cout << std::hex << rgb;

В зависимости от порядкового номера вашей системы вам может понадобиться поэкспериментировать с тем, какие байты длинной int вы задали. Мой пример перезаписывает байты 0-2, но вы можете записать байты 1-3. И вы можете написать порядок как z, y, x вместо x, y, z. Подобные детали зависят от платформы. Хотя если вы никогда не хотите печатать значение RGB, а просто хотите рассматривать его как хэш, вам не нужно беспокоиться о том, какие байты вы пишете или в каком порядке.

8 голосов
/ 26 июля 2011

Вы рассматривали вместо этого просто упаковку цветовых элементов в три байта целого числа?

uint32_t full_color = (x << 16) | (y << 8) | z;

2 голосов
/ 26 июля 2011

Используйте 3-символьный массив символов в качестве 24-битного представления и присвойте каждому символу значение одного из ваших входных значений.

2 голосов
/ 26 июля 2011

попробуй sprintf(xx,"%d%d%d",x,y,z);

1 голос
/ 26 июля 2011

Преобразование 3 байтов в биты и сохранение результата в массиве можно легко выполнить, как показано ниже:

void bytes2bits(unsigned char x, unsigned char y, unsigned char z, char * res)
{
    res += 24; *res-- = 0;
    unsigned xyz = (x<<16)+(y<<8)+z;
    for (size_t l = 0 ; l < 24 ; l++){
        *res-- = '0'+(xyz & 1); xyz >>= 1;
    }

}

Однако, если вы ищете способ хранения трехзначения байтов не двусмысленным и компактным образом, вы, вероятно, должны согласиться на шестнадцатеричное.(каждая группа из четырех бит двоичного представления соответствует цифре от 0 до 9 или букве от А до F).Это очень просто и очень просто для кодирования и декодирования, а также подходит для удобочитаемого вывода.

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

unsigned int key = (x<< 16)|(y<<8)|z;

Вы можете так же легко получить начальные значения из ключа, если это необходимо:

unsigned char x = (key >> 16) & 0xFF;
unsigned char y = (key >> 8) & 0xFF;
unsigned char z = key & 0xFF;
...