一个字节中的两个值
Two values in one byte
在单个nibble (0- f)中,我可以存储从0到15的一个数字。在一个字节中,我可以存储从0到255 (00 - FF)的单个数字。我可以使用一个字节(00- ff)来存储0-127 (00- 7F)范围内的两个不同的数字吗?
你的问题的答案是NO。可以将一个字节拆分为两个数字,但是这两个数字的位数之和必须为<= 8。因为范围0-127需要7位,字节中的其他数字只能是1位,即0-1。
由于基数的原因,不能将两个小整数存储在0…127的范围是0…255年范围内。换句话说,笛卡尔积[0;127]×[0;127]有214个元素,且大于28([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
中使用位字段。然后(最重要的是)以这种方式处理小块可能比使用字节更低效,代码可读性更差。
和更新单个nibble,例如使用
void update_left_nibble (uint8_t*p, unibble_t l) {
assert (p);
assert (l<=15);
*p = ((l<<4) | ((*p) & 0xf));
}
有时是昂贵的(它涉及内存负载和内存存储,因此使用CPU缓存和缓存一致性机制),最重要的是通常是非原子操作(如果两个不同的线程同时在相同的地址p
上调用update_left_nibble
会发生什么-即指针混叠-是未定义的行为)。
作为一个经验法则,避免在一个字节中打包超过一个数据项,除非你确定它是值得的(例如,你有十亿这样的数据项)。
一个字节不足以存储0…127中的两个值,因为每个值都需要log2(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-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年,实际上)。你只是失去了一些精度,类似于浮点类型。
您可以在单个字节中存储范围为0-15的两个数据,但您不应该这样做(一个var =一个数据是更好的设计)。
如果必须的话,可以使用位掩码和位移位来访问变量中的两个数据。
uint8_t var; /* range 0-255 */
data1 = (var & 0x0F); /* range 0-15 */
data2 = (var & 0xF0) >> 4; /* range 0-15 */
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?
- 在编译时而不是运行时创建一个由两个字节组成的值
- 在"C++代码"部分中,可能会写入两个字节
- 如何封装两个容器之间的传输字节
- 包含消息长度的两个字节标头上的部分recv()呢?
- 如何分别通过 QSslSocket 发送两个字节
- 在java中将两个字节(一个正字节和另一个负字节)合并为短字节
- SDL2_ttf无法呈现长度超过两个字节的字符吗?
- 一次读取两个字节的.dat文件
- C++两个字节上写一个数字
- 如何将 BYTE 数组中的两个字节存储为 int(或类似的东西)
- 将两个字节放在一起
- 如何将两个字节*(秒块)与运算符连接起来'secblock<T, A>::operator+='
- Arduino将整数发送为两个字节,并将其显示在Qt中
- 两个字节合一
- 将单词拆分为两个字节的最快方法
- QByteArray::number(int)只有两个字节长
- 使用std::copy将char数组中的两个字节复制到无符号short中
- 将两个字节转换为16位值的最有效方法
- 为什么CString(LPCTSTR lpsz)构造函数检查lpsz的高两个字节