2015-10-09 2 views
2

В одном полубайте (0-F) я могу сохранить одно число от 0 до 15. В одном байте я могу сохранить одно число от 0 до 255 (00 - FF). Могу ли я использовать байт (00-FF) для хранения двух разных чисел в диапазоне 0-127 (00-7F)?Два значения в одном байте

+0

В одном байте вы можете хранить значения от 0 до 255. Вы сбиты с толку четырьмя битами, которые часто представлены как одна шестнадцатеричная цифра (число или буква А-F). Две из этих цифр - это байт. – GolezTrol

+0

Я отредактировал мой вопрос, спасибо – pistacchio

+1

Прежде всего 4 бит позволяют хранить значение от 0 до 15. – LPs

ответ

10

Ответ на ваш вопрос НЕТ. Вы можете разделить один байт на два числа, но сумма бит в двух числах должна быть < = 8. Поскольку для диапазона 0-127 требуется 7 бит, другой номер в байте может быть только 1 бит , т. е. 0-1.

4

Для очевидных cardinality причинам вы не можете сохранить два небольших целых числа в диапазоне 0 ... 127 в одном байте диапазона 0 ... 255. Другими словами cartesian product [0; 127] × [0; 127] имеет 2 элементы, которые больше, чем 2 (кардинальное из [0; 255] интервал, для байтов)

(Если вы можете позволить себе потерять точность, о которой вы не сказали, вы могли бы, например, сохранить только самые высокие бит ...)

Возможно, ваш вопрос: могу ли я хранить два небольших целых числа от [0; 15 ] в байте? Тогда, конечно, вы могли бы:

typedef unsigned unibble_t; // unsigned nibble in [0;15] 
uint8_t make_from_two_nibbles(unibble_t l, unibble_t r) { 
    assert(l<=15); 
    assert(r<=15); 
    return (l<<4) | r; 
} 

unibble_t left_nible (uint8_t x) { return x >> 4; } 
unibble_t right_nibble (uint8_t) { return x & 0xf; } 

Но я не думаю, что вы всегда должны это делать. Во-первых, вы можете использовать битовые поля в struct. Затем (и, самое главное), когда дело касается кусочков, этот способ может быть более неэффективным и сделать менее читаемый код, чем использование байтов.

И обновление одного полубайта, например. с

void update_left_nibble (uint8_t*p, unibble_t l) { 
    assert (p); 
    assert (l<=15); 
    *p = ((l<<4) | ((*p) & 0xf)); 

}

иногда дорого (она включает в себя загрузку памяти и хранилище памяти, поэтому использует CPU cache и cache coherence машины), а самое главное, как правило, не- atomic операции (что произойдет, если два разных потока одновременно звонят update_left_nibble на то же адрес p -е с pointer aliasing - is undefined behavior).

Как правило, избегайте упаковки более одного элемента данных в байт, если вы не уверены, что это стоит (например, у вас есть миллиард таких элементов данных).

-1

Вы можете сохранить два данных в диапазоне 0-15 в одном байте, но вы не должны (один var = один - лучший дизайн).

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

uint8_t var; /* range 0-255 */ 

data1 = (var & 0x0F);  /* range 0-15 */ 
data2 = (var & 0xF0) >> 4; /* range 0-15 */ 
+0

Вы должны добавить точность на * хранить 2 числа в диапазоне ** 0-15 **, * потому что ОП запросил 2 числа в диапазоне ** 0-127 ** ... –

-1

Могу ли я использовать байты для хранения двух чисел в диапазоне 0-127?

Конечно, вы можете:

uint8_t storeTwoNumbers(unsigned a, unsigned b) { 
    return ((a >> 4) & 0x0f) | (b & 0xf0); 
} 

uint8_t retrieveTwoNumbers(uint8_t byte, unsigned *a, unsigned *b) { 
    *b = byte & 0xf0; 
    *a = (byte & 0x0f) << 4; 
} 

Числа по-прежнему в диапазоне 0 ... 127 (0 ... 255, на самом деле). Вы просто теряете некоторую точность, подобно типам с плавающей запятой.Их значения увеличиваются с шагом 16.

+0

Тот же ответ, что и [мой] (http: //stackoverflow.com/a/33031605/841108), а не то, что спросил ОП. Он хочет сохранить два числа [0; 127] в байте [0; 255] –

+0

@BasileStarynkevitch. Если я получу вас правильно, вы сохраняете два целых числа в диапазоне 0..15 в одном байте. Мой ответ берет вопрос буквально и сохраняет два целых числа в диапазоне 0..127 в одном байте. Он делает это, уменьшая наименее значимые биты, не самые важные, как в вашем ответе. –

+0

Вопрос OP: Можно ли использовать байт (00-FF) для хранения двух разных чисел в диапазоне 0-127 (00 - 7F) .... Таким образом, единственный короткий ответ: НЕТ. – LPs

0

Один байт недостаточно для двух значений в 0 ... 127, так как для каждого из этих значений требуется журнал (128) = 7 бит, в общей сложности 14, но байт составляет всего 8 бит.

Вы можете объявлять переменные с битом упакованы хранениями с использованием C и C++ битовых синтаксиса:

struct packed_values { 
    uint8_t first : 7; 
    uint8_t second : 7; 
    uint8_t third : 2; 
}; 

В этом примере, sizeof(packed_values) должен быть равен 2, потому что были использованы только 16 бит, несмотря на три поля.

Это проще, чем с помощью побитового арифметику с << и & операторов, но это все-таки не совсем такой же, как обычные переменные: битовые поля не имеют адреса, поэтому вы не можете иметь указатель (ссылку или C++) к одному ,