Reputation: 75
I have a sensor that stores the recorded information as a .pcap file. I have managed to load the file into an unsigned char array. the sensor stores information in a unique format. For instance representing an angle of 290.16, it stores the information as binary equivalent of 0x58 0x71.
what I have to do to get the correct angle is that concatenate 0x71 and 0x58 then convert the resultant hex value into a decimal divide it by 100 and then store it for further analysis.
My current approach is this:
//all header files are included
main
{
unsigned char data[50]; //I actually have the data loaded in this from a file
data[40] = 0x58;
data[41] = 0x71;
// The above maybe incorrect. What i am trying to imply is that if i use the statement
// printf("%.2x %.2x", data[40],data[41]);
// the resultant output you see on screen is
// 58 71
//I get the decimal value i wanted using the below statement
float gar = hex2Dec(dec2Hex(data[41])+dec2Hex(data[40]))/100.0;
}
hex2Dec and dec2Hex are my own functions.
unsigned int hex2Dec (const string Hex)
{
unsigned int DecimalValue = 0;
for (unsigned int i = 0; i < Hex.size(); ++i)
{
DecimalValue = DecimalValue * 16 + hexChar2Decimal (Hex[i]);
}
return DecimalValue;
}
string dec2Hex (unsigned int Decimal)
{
string Hex = "";
while (Decimal != 0)
{
int HexValue = Decimal % 16;
// convert deimal value to a Hex digit
char HexChar = (HexValue <= 9 && HexValue >= 0 ) ?
static_cast<char>(HexValue + '0' ) : static_cast<char> (HexValue - 10 + 'A');
Hex = HexChar + Hex;
Decimal = Decimal /16;
}
return Hex;
}
int hexChar2Decimal (char Ch)
{
Ch= toupper(Ch); //Change the chara to upper case
if (Ch>= 'A' && Ch<= 'F')
{
return 10 + Ch- 'A';
}
else
return Ch- '0';
}
The pain is that I have to do this conversion billions of time which really slows down the process. Is there any other efficient way to deal with this case?
A matlab code that my friend developed for a similar sensor, took him 3 hours to extract data that was worth only 1 minute of real time. I really need it to be as fast as possible.
Upvotes: 2
Views: 1530
Reputation:
As far as I can tell this does the same as
float gar = ((data[45]<<8)+data[44])/100.0;
For:
unsigned char data[50];
data[44] = 0x58;
data[45] = 0x71;
the value of gar
will be 290.16
.
Explanation:
It is not necessary to convert the value of an integer to a string to get the hex value, because decimal, hexadecimal, binary, etc. are only different representations of the same value. data[45]<<8
shifts the value of data[45]
eight bits to the left. Before the operation is performed the type of the operand is promoted to int
(except for some unusual implementations where it might be unsigned int
), so the new data type should be large enough to not overflow. Shifting eight bits to the left is equivalent to shifting 2 digits to the left in hexadecimal representation. So the result is 0x7100
. Then the value of data[44]
is added to that and you get 0x7158
. The result of type int
is then cast to float
and divided by 100.0
.
In general int
might be too small to apply the shift operation without shifting the sign if it is only 16-bit long. If you want to cover that case then explicitly cast to unsigned int
:
float gar = (((unsigned int)data[45]<<8)+data[44])/100.0;
Upvotes: 1
Reputation: 674
In here C convert hex to decimal format, Emil H posted some sample code that looks very similar to what you want.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *hex_value_string = "deadbeef";
unsigned int out;
sscanf(hex_value_string, "%x", &out);
printf("%o %o\n", out, 0xdeadbeef);
printf("%x %x\n", out, 0xdeadbeef);
return 0;
}
Your conversion functions don't look particularly efficient, so hopefully this is faster.
Upvotes: 0