我有问题要解决,不知道该怎么做。我的程序从带有十六进制值的串行端口字符串(如DFF7DF)接收。我需要将其转换为二进制形式,丢弃前四位,将第五位作为符号位,接下来将12位作为值。
我需要获得正常INT值。
我能够在MATLAB中创建这样的程序,但我需要C ++才能在我的linux arm板上运行它。
提前感谢您的帮助! 马尔钦
答案 0 :(得分:5)
您可以执行以下操作:
unsigned long value = strtoul("DFF7DF", NULL, 16);
value >>= 4; // discard first four bits
printf("Minus sign: %s\n", value & 1 ? "yes" : "no");
printf("Value: %lu\n", (value & 0x1FFF) >> 1);
long newvalue = (value & 1 ? -1 : 1) * ((value & 0x1FFF) >> 1);
答案 1 :(得分:2)
正确答案取决于几个约定 - 是十六进制字符串big-endian还是little-endian?你是从最重要或最不重要的位开始计数位吗?是否总会有6个十六进制字符(24位)?
无论如何,这是一个大端的解决方案,总是24位,从最高位开始计算。如果我的一些假设是错误的,我相信你能够适应它。
int HexToInt(char *hex)
{
int result = 0;
for(;*hex;hex++)
{
result <<= 4;
if ( *hex >= '0' && *hex <= '9' )
result |= *hex-'0';
else
result |= *hex-'A';
}
return result;
}
char *data = GetDataFromSerialPortStream();
int rawValue = HexToInt(data);
int sign = rawValue & 0x10000;
int value = (sign?-1:1) * ((rawValue >> 4) & 0xFFF);
答案 2 :(得分:1)
问题是标记C ++,但每个人都在使用C字符串。以下是使用C ++ STL字符串
的方法std::string s("DFF7DF");
int val;
std::istringstream iss(s);
iss >> std::setbase(16) >> val;
int result = val & 0xFFF; // take bottom 12 bits
if (val & 0x1000) // assume sign + magnitude encoding
result = - result;
(第二个“小小的”部分不清楚你的问题。如果你澄清,我会更新答案。)
答案 3 :(得分:0)
你必须检查你的机器类型是否有结束,但这基本上就是这个想法。
const char * string = "DFF7DF";
const unsigned char second_nibble = hex_to_int (string[1]);
const unsigned char third_nibble = hex_to_int (string[2));
const unsigned char fourth_nibble = hex_to_int (string[2));
int sign = second_nibble & (1<<3) ? -1 : 1;
unsigned value = unsigned (second_nibble & ~(1<<3)) << 12-3; // Next three bits are in second nibble
value |= (unsigned(third_nibble)<<1) | (fourth_nibble&1); // Next 9 bits are in the next two nibbles.
确保在unsigned
类型上执行位移操作符。
答案 4 :(得分:-1)
以下是一种模式:
const char* s = "11";
istringstream in(string(s, 3));
unsigned i=0;
in >> hex >> i;
cout << "i=" << dec << i << endl;
其余的只是一点点转移。