HEX and binary operations

I have a problem to solve and don’t know how to do it. My program receives from a serial port string with a hexadecimal value (e.g. DFF7DF). I need to convert it to binary, discard the first four bits, take the fifth bit as a sign bit and the next 12 bits as a value.

I need to get the value like regular INT.

I was able to make such a program in MATLAB, but I need C ++ to be able to run it on my linux arm board.

Thanks in advance for your help! Marcin

+4
source share
5 answers

You can do something like:

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); 
+4
source

The correct answer depends on several conventions - is it a hexagonal line big-endian or little-endian? Are you starting to read bits from the most significant or least significant bit? Will there always be exactly 6 hexadecimal characters (24 bits)?

In any case, here is one solution for buy-din, always-24-bit, counting from the most significant bit. I am sure you can adapt it if some of my assumptions are wrong.

 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
source

The question is tagged C ++, but everyone uses the C string. Here's how to do it with the C ++ STL string

 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; 

(The second part of the "grunt" is not clear from your question. I will update the answer if you clarify this.)

+1
source

You should check your machine type for endian-ness, but this is basically an idea.

 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. 

Make sure that you perform bit change operations in unsigned types.

0
source

Here is an example:

 const char* s = "11"; istringstream in(string(s, 3)); unsigned i=0; in >> hex >> i; cout << "i=" << dec << i << endl; 

The rest just flushes the bit.

-1
source

All Articles