HughStevenJames
HughStevenJames

Reputation: 11

Interpreting a hex number as decimal

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

Answers (3)

TripeHound
TripeHound

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

Jens Gustedt
Jens Gustedt

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

Manuel Selva
Manuel Selva

Reputation: 19050

Checking if your string starts with 0x characters and removing them should do the trick.

Upvotes: 0

Related Questions