## How to parse Hex to Decimal in C?

10 posts / 0 new
Author
Message

Hello everybody!

IÂ´m having a hard time trying to crack some code for a this conversion but looks like IÂ´m too rusty to solve this puzzle. By the way, IÂ´m like a newbie in C:

I have the following example:

LetÂ´s say I have in uint8_t hexsum = 0xb6, which is 182 in decimal, I need to extract just the less significant decimal digit 2.

Searched the web for over an hour without finding anything which could solve this.

Any code suggestions?

Thank you!

Good Soldering JRGandara

```#include
char buff [8];
int main(void) {
volatile char digit;
uint8_t hexsum = 0xb6;
itoa(hexsum, buff, 10);
digit = buff[strlen(buff)-1];
}```

That will set 'digit' to '2'. If you actually want binary 2 then:

`  digit = buff[strlen(buff)-1] -  '0';`

(BTW I only made digit 'volatile' otherwise the optimiser would eat all this pointless code ;-))

Cliff, was it your intention to write it more complicated than necessary? ;-)

Binary:

`digit = hexsum % 10;`

ASCII:

`digit = (hexsum % 10) + '0';`

Stefan Ernst

Only that I had a sneaking suspicion that there may be a later requirement to do something similar to the other digits ;-)

@OP, the itoa() I used is (roughly) a lot of repeated %10's

Wow!

That was fast! One line of code for something like that is amazing! And showed me how far from be a C programmer IÂ´m. I have worked a lot with Assembly for Atmel, always reluctant to start with C, but now there is not return.

Thank you guys! Worked like a charm!

Good Soldering JRGandara

Remember, in integer math, modulus (%) is your friend!

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut.

Sometimes. Modulo is a divide operation so can be costly in time and space.

(I recently optimised some image processing where a repeated % cost about 15% of the overall time).

if you only need this for byte size it can easy be done in ASM, and I guess ok in C at least on a mega.
If you multiply your number with 205 (in C you have to make a 16bit multiplication) and then >>11, I hope the C will take High byte only and >>3.
This is a correct /10 for all values.(unsigned!)
Find the reminder the normal way, but this time it can all be done in 8bit.
Somewhere in this forum I have posted a 16 bit to BCD routine in ASM that max take 68 clk as I remember.

this is a small test (sorry for all the typecast but then I know what is going on). I write the result to a port so the optimizer don't remove the code. (volatile would add a lot of code).

```#include
unsigned char i;
unsigned int a;

int main(void){

while (1){
i++;
a=((unsigned char)205*i)>>(unsigned char)11;
PORTB=i-(unsigned char)10*(unsigned char)a;
}
}
```

And the output:

```ce:	20 91 00 01 	lds	r18, 0x0100
d2:	2f 5f       	subi	r18, 0xFF	; 255

while (1){
i++;
a=((unsigned char)205*i)>>(unsigned char)11;
PORTB=i-(unsigned char)10*(unsigned char)a;
d4:	3d ec       	ldi	r19, 0xCD	; 205
d6:	46 ef       	ldi	r20, 0xF6	; 246
d8:	5f ef       	ldi	r21, 0xFF	; 255
da:	23 9f       	mul	r18, r19
dc:	c0 01       	movw	r24, r0
de:	11 24       	eor	r1, r1
e0:	80 e2       	ldi	r24, 0x20	; 32
e2:	98 02       	muls	r25, r24
e4:	81 2d       	mov	r24, r1
e6:	99 0b       	sbc	r25, r25
e8:	11 24       	eor	r1, r1
ea:	84 9f       	mul	r24, r20
ec:	80 2d       	mov	r24, r0
ee:	11 24       	eor	r1, r1
f0:	82 0f       	add	r24, r18
f2:	88 bb       	out	0x18, r24	; 24
f4:	2f 5f       	subi	r18, 0xFF	; 255
f6:	f1 cf       	rjmp	.-30     	; 0xda
```

Only count the converter part of the code it's done in 18clk not bad.
This only works (good) for AVR's with a HW multiplyer.
(for a tiny the code take about 150 clk)

And the same code in ASM:

```;input r18
;output r24
;change r0,r1,r19

ldi r18,0
top:
ldi r19,205
mul r18,r19
lsr r1
lsr r1
lsr r1
ldi r19,10
mul r1,r19
mov r24,r18
sub r24,r0
inc r18
rjmp top
```

11 clk for the converter code.