我有一个范围为[-8,7]的整数数组,我想把它们写在一个二进制文件中。由于4位足以表示这些数字,我想把每两个元素压缩在一个8位整数中,这样我就得到了一个更小的文件。这是我到目前为止所做的:
#include <iostream>
#include <stdint.h>
int main()
{
int8_t a1{-1}, a2{1};
uint8_t a1_4bit = (((uint8_t)a1 & 0b10000000) >> 4) + (uint8_t)a1 & 0b00000111;
uint8_t a2_4bit = (((uint8_t)a2 & 0b10000000) >> 4) + (uint8_t)a2 & 0b00000111;
uint8_t compact_a = (a1_4bit << 4) + a2_4bit;
return 0;
}
字符串
我在这里尝试做的是我把符号位和三个LSB位放在一起。但是当我试图从compact_a
中提取原始整数时,我得到7
和1
,而不是-1
和1
。我用于提取原始数字的代码是:
uint8_t a_re = compact_a/16 ;
uint8_t a_im = compact_a%16 ;
a_re = a_re << 4 ;
a_im = a_im << 4 ;
int8_t a_re2 = *(int8_t *) &a_re ;
int8_t a_im2 = *(int8_t *) &a_im ;
a_re2 = a_re2 >> 4 ;
a_im2 = a_im2 >> 4 ;
型
我不确定第一个代码片段是否具有误导性或有用,因此,无论是对我的代码进行更新还是使用完全不同的方法,都值得赞赏。
3条答案
按热度按时间iq0todco1#
这里的问题是运算符优先级。如果您更改
字符串
是
型
(note右侧部分的额外括号),它将按预期工作。
Demo
请注意,由于您正在执行按位运算,因此请使用|而不是作为一般规则使用+,以避免在以后一些项目中出现意外的符号问题。
gdx19jrr2#
掩码
0b00000111
似乎是错误的。你需要四位,即掩码0b1111
。我不完全确定我是否理解你的方法。基本思想是,范围
[-8, 7]
中的整数可以用4位二进制补码整数表示。自C++20起,有符号整数保证用二进制补码表示,这意味着:int
)是通过对最少的4位进行位屏蔽来完成的int
)是通过符号扩展完成的字符串
这个打印
型
请特别注意
sx4
函数,它将一个4位二进制补码有符号整数进行符号扩展,形成一个32位二进制补码有符号整数。sx4
基本上将8
Map到-8
,将9
Map到-7
,.将15
Map到-1
。bjg7j2ky3#
下面的代码展示了如何在一个字节中存储任何一对介于-8和7之间的整数。但是,在提取数字时,它确实依赖于一些实现定义的行为:具体来说,它假设编译器在对负数使用
>>
时进行算术右移(即保留符号)。字符串