В одном полубайте (0-F) я могу сохранить одно число от 0 до 15. В одном байте я могу сохранить одно число от 0 до 255 (00 - FF). Могу ли я использовать байт (00-FF) для хранения двух разных чисел в диапазоне 0-127 (00-7F)?Два значения в одном байте
ответ
Ответ на ваш вопрос НЕТ. Вы можете разделить один байт на два числа, но сумма бит в двух числах должна быть < = 8. Поскольку для диапазона 0-127 требуется 7 бит, другой номер в байте может быть только 1 бит , т. е. 0-1.
Для очевидных 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).
Как правило, избегайте упаковки более одного элемента данных в байт, если вы не уверены, что это стоит (например, у вас есть миллиард таких элементов данных).
Вы можете сохранить два данных в диапазоне 0-15 в одном байте, но вы не должны (один var = один - лучший дизайн).
Если необходимо, вы можете использовать бит-маски и бит-сдвиги для доступа к двум данным в вашей переменной.
uint8_t var; /* range 0-255 */
data1 = (var & 0x0F); /* range 0-15 */
data2 = (var & 0xF0) >> 4; /* range 0-15 */
Вы должны добавить точность на * хранить 2 числа в диапазоне ** 0-15 **, * потому что ОП запросил 2 числа в диапазоне ** 0-127 ** ... –
Могу ли я использовать байты для хранения двух чисел в диапазоне 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.
Тот же ответ, что и [мой] (http: //stackoverflow.com/a/33031605/841108), а не то, что спросил ОП. Он хочет сохранить два числа [0; 127] в байте [0; 255] –
@BasileStarynkevitch. Если я получу вас правильно, вы сохраняете два целых числа в диапазоне 0..15 в одном байте. Мой ответ берет вопрос буквально и сохраняет два целых числа в диапазоне 0..127 в одном байте. Он делает это, уменьшая наименее значимые биты, не самые важные, как в вашем ответе. –
Вопрос OP: Можно ли использовать байт (00-FF) для хранения двух разных чисел в диапазоне 0-127 (00 - 7F) .... Таким образом, единственный короткий ответ: НЕТ. – LPs
Один байт недостаточно для двух значений в 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++) к одному ,
В одном байте вы можете хранить значения от 0 до 255. Вы сбиты с толку четырьмя битами, которые часто представлены как одна шестнадцатеричная цифра (число или буква А-F). Две из этих цифр - это байт. – GolezTrol
Я отредактировал мой вопрос, спасибо – pistacchio
Прежде всего 4 бит позволяют хранить значение от 0 до 15. – LPs