0

I'm looking to convert a input variable of this type:

char var[] = "9876543210000"

to a hex equivalent char

char hex[] = "08FB8FD98210"

I can perform this by e.g. the following code::

long long int freq;
char hex[12];
freq = strtoll(var,NULL,10);
sprintf(hex, "%llX",freq);

However I'm doing this on a avr microcontroller, thus strtoll is not available only strtol (avr-libgcc). So I'm restricted to 32 bits integer which is not enough. Any ideas?

Best regards Simon

4
  • Which part of implementing yourself from scratch it is not clear to you? BTW, strtoll is a standard C function, and should be available on any conforming compiler. Commented Nov 14, 2016 at 18:06
  • If, what I understand you say, the avr microcontroller is restricted to 32 bit integers, then you must reconsider what the input is (means) and find a different way to split it into its parts. Commented Nov 14, 2016 at 18:12
  • @EugeneSh. strtoll is not available in avr-libc nongnu.org/avr-libc/user-manual/group__avr__stdlib.html Commented Nov 14, 2016 at 18:19
  • Couldn't you just split the input string into two parts (limiting the length to -let's say- max 8 digits per part), and convert the right and the left part part separately using strtol(). The multiply the result of the left part by the appropriate factor (10^x, where x=number of digits of the right part) and add the result from the right. Commented Nov 15, 2016 at 14:33

3 Answers 3

2

Yes.... this method works fine only with positive number, so if you have a minus sign, just save it before doing next. Just divide the string number in two halves, lets say that you select six digit each, to get two decimal numbers: u_int32_t left_part; and u_int32_t right_part; with the two halves of your number.... you can construct your 64 bit number as follows:

u_int64_t number = (u_int64_t) left_part * 1000000 + right_part;

If you have the same problem on the printing side, that is, you cannot print but 32 bit hex numbers, you can just get left_part = number >> 32; and right_part = number & 0xffffffff; and finally print both with:

if (left_part) printf("%x%08x", left_part, right_part);
else printf("%x", right_part);

the test makes result not to be forced to 8 digits when it is less than 0x100000000.

Sign up to request clarification or add additional context in comments.

1 Comment

This worked great thanks! However there seems to be something that I dont understand with the precision. E.g. the char* = "1000000000000" is converted to 999999995904, do you know why I don't get exactly the same number? This is only the case when I do it on C for AVR on my microcontroller not with pure C.
2

It looks like you might have to parse the input one digit at a time, and save the result into a uint64_t variable.

Initialize the uint64_t result variable to 0. In a loop, multiply the result by 10 and add the next digit converted to an int.

Now to print the number out in hex, you can use sprintf() twice. First print result >> 32 as a long unsigned int, followed by (long unsigned int)result at &hex[4](or 6 or 8 or wherever) to pick up the remaining 32 bits.

You will need to specify the format correctly to get the characters in the array in the correct places. Perhaps, just pad it with 0s? Don't forget about room for the trailing null character.

Comments

1

Change this:

freq = strtoll(var,NULL,10);

To this:

sscanf(var,"%lld",&freq);

3 Comments

The ll option is not available in the avr library. It only has an l option for int32_t or double.
@UncleO: OP has only mentioned the lack of strtoll. Are you saying that no 64-bit operations or operands (i.e., long long) are viable?
64-bit operations are available, but no strtoll or ll options for scanf. http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.