ASCII to DEC

Hi.

I need to translate a 10 digits ASCII number to 10 digits DEC number.

My serial RS232 RFID reader say 0102FFD37E and I want show on LCD the dec translate: 4345287550.
How can do it?

...
...

while (Serial.available()){
strArray = Serial.read();

  • i++;*
    ...
    ...
    (Sorry, i am not speak english very well)

That is a 40 bit number, the arduino can't handle numbers that big so there is no point in even trying to make it into a number. Just keep it as a string.
Why do you want to show it in decimal anyway?

Since grumpy mike says it's too big a number, you'll have to deal with the string. Trouble is you're going to have to carry numbers.

If you're going through in order, then you'll deal with the 0 first, then 1 ... which means that if your hex digit is a-f then you'll have to increment your previous digit strArray[i-1].

Also, you'll have to check whether the first digit is A-F. If it is, you'll have to add in an extra digit to cover the 1. So, add a 1 at i, increment i, then add the remainder and proceed as normal.

There's probably a better way, but you could use a case statement to convert the hex to bin.

http://gmplib.org/

Thanks for your fast Replies.

The software on my RFID access control needs to put the number in decimal, and need to know the taj number.

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.

Thank you davekw7x. I'll tell you.