[С++] последовательность бит в число, быстро

Devid

Есть целое знаковое число (4 байта закодированное в последовательность бит следующим образом:
1) Первый бит каждого байта равен 0 если число не закончилось и 1 если это последний байт.
2) Второй бит первого байта обозначает знак.
Надо быстро получить из такой последовательности (например в виде вектора unsigned char) число int. Как это можно сделать?

pitrik2

Есть целое знаковое число (4 байта закодированное в последовательность бит следующим образом:
1) Первый бит каждого байта равен 0 если число не закончилось и 1 если это последний байт.
2) Второй бит первого байта обозначает знак.
а где пункт 3?
что в остальных то битах?
как минимум нада знать какой там эндиан
а так - может там ваще всё выворот на выворот :)

Devid

big-endian, если число положительное то первые нули обрезаются, если отрицательное - то первые единицы. Собственно нужен не непосредственно код, а просто общие соображения. Например, нормально ли использовать memcpy для конвертации уже нормальной последовательности бит (в виде массива или вектора unsigned char) в число?

klyv

ненормально.

Devid

ненормально.
Спасибо. А как правильно?

klyv

А как правильно?
либо с учётом endian (и не забыв проверить битность системы) делать грязные хаки (типа *(int*&ar[0]) либо битовой арифметикой - ar[0] << 24 + ar[1] << 16 + ar[2] << 8 + ar[3]

pitrik2

используй сдвиги
>> и <<
int сколько там байт занимает? если нехватает то используй long int
long int result;
1 байт
result = a[1] && 1<<8-1 && 1<<7-1
if a[1] & 1<<8 > 0
2 байт
result <<= 7;
result | = (a[2] && 1<<8-1)
иф 2, иф 3
end if
в конце ставим знак
if a[1] & 1<<7 > 0
result = -result
end if

pitrik2

либо битовой арифметикой - ar[0] << 24 + ar[1] << 16 + ar[2] << 8 + ar[3]
там не так просто изза того что число может кончиться

Devid

result = -result
Тут должно быть result = result - 256*256*256*256, только это некрасиво выглядит.

klyv

Тут должно быть result = result - 256*256*256*256, только это некрасиво выглядит.
result -= 1 << (8 * 4)

klyv

там не так просто изза того что число может кончиться
Вопрос был такой:
Например, нормально ли использовать memcpy для конвертации уже нормальной последовательности бит (в виде массива или вектора unsigned char) в число?
;)

Devid

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

Devid

1 << (8 * 4)
Это 0 :(

kokoc88

Это 0
Ну просто 256*256*256*256 не помещается в 4 байта, про которые ты написал в условии задачи.

klyv

а, да, надо не столько вычитать.
а 1 << (8*4 - 1) можно ещё без вычитания обойтись: result &= ~(1 << (8*4 - 1 :)
а ещё под нашу музыку можно много чего делать

ppplva

1LL << (8 * 4)

pitrik2

Тут должно быть result = result - 256*256*256*256, только это некрасиво выглядит.
ну этого в условии не было
я тут просто схематически показал что нада знак изменить
как уж там правильно менять по твому алгоритму - тебе видней

pitrik2

а 1 << (8*4 - 1) можно ещё без вычитания обойтись: result &= ~(1 << (8*4 - 1 :)
от не люблю я енту операцию инвертирования ~
она не наглядная, нужно думать сколько же там старших байтов осталось, т.е. сколько единичек в результе получится

Devid

она не наглядная,
Гы, в итоге
result = result | ( 1 << (32 - k - 1) ^ (-1) );
получилось. Вот это точно не наглядно.

klyv

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