Reputation: 11
I have an embedded system running C-code which works pretty straightforwardly; it reads characters via a serial connection, interprets the received chars as hexadecimal numbers and depending on what was received, proceeds to do something else. However, there is one very special case where the chars received are decimal instead of hex. Since this case is very rare (kind of an error case of an error case), I don't wish to modify the actual character reception to decide whether to interpret the received value as dec or hex, but rather to add a quick algorithm into the case handling where I change the number into decimal.
What would you say is the fastest (as in most efficient processor-wise) way of doing this? Since the software is running on a small MCU, any C library functions are not an option since I don't wish to add any more unnecessary #include's, so a purely mathematical algorithm is what I'm searching for.
Just to be clear, I'm not asking the quickest way to do a basic hex-to-dec- conversion as in 0x45 -> dec 69, but what I want to do is to transform eg. 0x120 into decimal 120.
Thanks in advance!
EDIT: Sorry, I'll try to explain in more detail. The actual code is way too long, and I think pasting it here is unnecessary. So here's what happens:
First I read a received number from the serial line, let's say "25". Then I turn it into hex number, so I have a variable with the read value, let's say X = 0x25. This works already fine, and I don't want to do modifications to this. What I would like to do now in this very special case is just to change the interpretation of the variable so that instead of X == 0x25, X==25. Hexadecimal 0x25 turns into decimal 25. There has to be some kind of mathematical formula for such a change, without the need of any processor-specific instructions or library functions?
Upvotes: 1
Views: 1162
Reputation: 2960
If I'm understanding correctly, you've already converted a stream of ASCII characters into a char/int
variable, assuming them to be a stream of hex-digits. In some cases, they were actually a stream of decimal digits (e.g. you received 45
and, treating this as hex, got a variable with value 69
when -- in one special case -- you actuially want its value to be 45
.
Assuming two-characters, (00
-ff
in general, but for "was meant to be decimal" we're talking 00
-99
) then:
int hexVal = GetHexStringFromSerialPort() ;
int decVal = 10*(hexVal >> 4) + (hexVal & 0x0f) ;
should do the trick. If you've got longer strings, you'll need to extend the concept further.
Upvotes: 4
Reputation: 78903
Just do a simple while
loop like this, supposing onum
and dnum
are unsigned integers
dnum = 0;
while (onum) {
digit = onum & 0xF;
dnum = dnum*10 + digit;
onum >>= 4;
}
this supposes that onum
is really of the form that you describe (no hexdigits that are >9
). It just succs the least significant hexdigit out of your number and adds it to your decimal.
Upvotes: 1
Reputation: 19050
Checking if your string starts with 0x
characters and removing them should do the trick.
Upvotes: 0