I'm not sure exactly what you need to do with the large integer. (Do you need to do some arithmetic or comparison with other large integers or what?)
Anyhow...
Here's the deal:
// The good news: avr-gcc supports 64-bit ints and
// operations thereon.
//
// The less-than-good news:
// Neither avr-libc nor Arduino libraries have functions
// to convert from ASCII to 64-bit ints and back. Also
// missing are functions to print out 64-bit ints.
//
// You can create those kinds of functions yourself if
// you need them.
//
// So...
//
// Here are a couple of example functions.
//
// hex_str_to_ll() converts a C-style "string" of ASCII hex digits
// to a 64-bit unsigned int
//
// ll_to_decimal_str() converts an unsigned 64 bit int to
// a C-style "string" representing the decimal value in a buffer
//
//
// davekw7x
#include <ctype.h> //for standard library functions isxdigit() and toupper()
//
// In a user program, some input routine would present a
// "string" of hex digits. I'll start with a "string" that
// represents a number close to the maximum 64-bit integer
//
char *cx = "FFFFFFFFFFFFFFF0";
uint64_t x;
void setup()
{
Serial.begin(9600);
Serial.print("Initially, as string of hex digits: cx = ");
Serial.println(cx);
Serial.println();
x = hex_str_to_ll(cx); // Convert to long-long integer
}
void loop()
{
char buffer[100];
uint32_t xhi = x >> 32;
uint32_t xlo = x;
sprintf(buffer, "With sprintf : x = 0x%08lx%08lx",xhi, xlo);
Serial.println(buffer);
Serial.print("As decimal string: x = ");
ll_to_decimal_str(x, buffer, sizeof(buffer));
Serial.println(buffer);
Serial.println();
++x; //Increment the 64-bit number
delay(5000);
}
//
// Extract decimal digits into a "string", least significant digit first.
// Then reverse the string.
//
void ll_to_decimal_str(uint64_t x, char *buffer, int size)
{
int i = 0;
printf("in ll_to_decimal_str: x = %lld\n", x);
for (i = 0; i < size-2 && x >= 10; i++) {
printf("i = %d", i);
buffer[i] = (x % 10) + '0';
x /= 10;
printf(", new x = %lld\n", x);
}
buffer[i++] = x + '0';
buffer[i] = '\0'; // Make sure the "string" is terminated properly
// Reverse the string.
// strrev is not a standard C library function, but
// it is supplied with avr-libc
buffer = strrev(buffer);
}
//
// If it isn't a hex digit, return -1
//
int ascii_hex_digit_to_bin(char ch)
{
char hex_digit_to_dec[] = "0123456789ABCDEF";
int i;
if (!isxdigit(ch)) {
return -1;
}
for (i = 0; i < 16; i++) {
if (toupper(ch) == hex_digit_to_dec[i]) {
break;
}
}
return i;
}
//
// TODO: Put in error checking that, somehow, sets or uses
// an error flag to indicate invalid input chars in the string
//
uint64_t hex_str_to_ll(const char *str)
{
uint64_t result = 0;
for (int i = 0; i < strlen(str); i++) {
result = (result * 16) + ascii_hex_digit_to_bin(str[i]);
}
return result;
}
Output:
Initially, as string of hex digits: cx = FFFFFFFFFFFFFFF0
With sprintf : x = 0xfffffffffffffff0
As decimal string: x = 18446744073709551600
With sprintf : x = 0xfffffffffffffff1
As decimal string: x = 18446744073709551601
With sprintf : x = 0xfffffffffffffff2
As decimal string: x = 18446744073709551602
With sprintf : x = 0xfffffffffffffff3
As decimal string: x = 18446744073709551603
.
.
.
I mean, it takes lots of CPU time and lots of program code to deal with 64-bit ints, but it can be done.
Now, regarding your original question about how to convert a "10 digits ASCII number to 10 digits DEC number": I will mention that the largest ten-digit hexadecimal number is 0xffffffffff
and its decimal representation is the 13-digit number 1099511627775
.
Regards,
Dave
Footnote:
ISO standard C++ does not mention the support of 64-bit integer data types, but the current ISO C language standard does. I guess that, since just about all C++ compilers come in a package that includes C compilers, most C++ compilers nowadays also support 64-bit integer data types. This is the case with the avr-gcc tool set.
When size is important, I use things defined in <stdint.h> rather than the non-length-specific data types int, long, long long, etc.
For example for many (most) compilers for desktop computers have int data types that are 32-bits long, whereas avr-gcc has 16-bit ints. Some desktop compilers have long ints that are 32 bits and some are 64 bits. If you ever go above and beyond the Wonderful World of Arduino, code portability may be important, and standard terminology might save some headaches.
In the meanwhile, for people who don't actually need 64-bit ints, the Arduino Way works (for most of us). You know: ints are 16 bits, longs are 32 bits. Stuff like that.