How to parse Hex to Decimal in C?

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#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 ;-))

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

Binary:

digit = hexsum % 10;

ASCII:

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

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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 

Not to bad code
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)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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.