View RSS Feed

alexan_e

Long integer to string function

Rate this Entry
This is a custom function to convert a number to the ASCII representation

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*****************************************************************************
** Function name:   ULongToStr
**
** Descriptions:    converts an unsigned long to ASCII characters and stores the result to a char array
**                  
** parameters:      unsigned long value : number to be converted
**                  char *str : pointer to the first char of the array
**                  char leading_zero : can be 0 so that trailing zeros are replaced with space or 1 to leave them as 0
**                  char digits : the number of digits that will be converted starting from the last digit of the provided number
**                                if you use 5 and the number is 123567890 then the array result will be 67890 (filling the first 5 chars of the array)
**                  
** Returned value:  None    
** 
*****************************************************************************/
void ULongToStr(unsigned long value, char *str,char leading_zero,char digits)
{
    char first_non_zero=1;
    str+=(digits-1);  // move the pointer to the last char of the array
    while (digits!=0)  // execute the loop for the times defined in digits variable
    {   if (value==0)   // if the remaining number is 0 then just add '0' to speed up the conversion
        {   *str='0';
            str--;  // move to the previous char of the array
        }
        else
        {
            *str = (char) ((value%10)+48); // find the digit value using modulo and assign the ASCII representation
            str--;  // move to the previous char of the array
            value= value/10;    // divide input input number by 10 for next loop
        }
        digits--;   // used as a counter to detect when we have reached the first char of the array
    }
 
    // at this point the array pointer is at the address &array[0]-1
    if (leading_zero==0)    // if parameter is set for no leading zeros
    {
        while(first_non_zero==1)    // if the first digit of the number is not found
        {   str++;  // move to next array character
            if (*str=='0') *str=32;     // if digit value is ADCII 0 then replace with space (user selectable)
            else first_non_zero=0;      // else set the flag that the first digit of the number was found
 
        }
    }
}

to call it ULongToStr(value, my_char_array, leading_zero, digits);
where
value is an unsigned variable but can be modified to use a signed variable and you have to take care of the sign for negative numbers
my_char_array is a pointer to the first char of the array (the same as &my_char_array[0])
leading_zero can be 0 so that trailing zeros are replaced with space or 1 to leave them as 0
digits is the number of digits that will be converted starting from the last digit of the provided number, if you use 5 and the number is 123567890 then the array result will be 67890 (filling the first 5 chars of the array)

the routine takes about 12200 clocks (in AVR) for 10 characters and is reduced about 1000 cycles for each lower character count (9,8,7 etc) while sprintf takes about 2700 clock but at the same time this routine uses about 1500 bytes less space than sprintf.


-----------------------------------------------------------------------------------

This is a much faster function compared to the previous version, it is also about three times faster than sprintf, the parameters are exactly the same as the previous version but it gives a result in about 1100 cycles (12 times faster than the previous one) for 10 digits with input of 3999999999 (worse case input number), anything else will take less, for example the number 1234567890 will need about 770 clocks

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*****************************************************************************
** Function name:   ULongToStr
**
** Descriptions:    converts an unsigned long to ASCII characters and stores the result to a char array
**                  
** parameters:      unsigned long value : number to be converted
**                  char *str : pointer to the first char of the array
**                  char leading_zero : can be 0 so that trailing zeros are replaced with space or 1 to leave them as 0
**                  char digits : the number of digits that will be converted starting from the last digit of the provided number
**                                if you use 5 and the number is 123567890 then the array result will be 67890 (filling the first 5 chars of the array)
**                  
** Returned value:  None    
** 
*****************************************************************************/
void ULongToStr(unsigned long value, char *str, char leading_zero, char digits)
{
    static long powers[9] = {10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
    char temp_digit,digit_cnt=10,first_non_zero=1;
 
    while (digit_cnt!=1)  // initially this value is 10 so the loop is executed 9 times
    {
        temp_digit = 48;  // ASCII 0
        while (value >= powers[digit_cnt-2])  // while number bigger than power value
        {
            value -= powers[digit_cnt-2];       // subtract the power value
            temp_digit++;                       // and increase variable
        }
        if (digit_cnt<=digits) *str++ = temp_digit; // only store requested number of digits  
 
        digit_cnt--;   // used as a counter to detect when we have reached the last char of the array
    }
    *str = (char) value+48; // assign the last character
 
    if (leading_zero==0)   // if parameter is set for no leading zeros
    {   str-=digits;    // go to the first char of the array
        while(first_non_zero==1)    // if the first digit of the number is not found
        {   str++;  // move to next array character
            if (*str=='0') *str=32;      // if digit value is ADCII 0 then replace with space (user selectable)
            else first_non_zero=0;      // else set the flag that the first digit of the number was found
 
        }
    }
}

to call it ULongToStr(value, my_char_array, leading_zero, digits);
where
value is an unsigned variable but can be modified to use a signed variable and you have to take care of the sign for negative numbers
my_char_array is a pointer to the first char of the array (the same as &my_char_array[0])
leading_zero can be 0 so that trailing zeros are replaced with space or 1 to leave them as 0
digits is the number of digits that will be converted starting from the last digit of the provided number, if you use 5 and the number is 123567890 then the array result will be 67890 (filling the first 5 chars of the array)

Alex

Updated 1st November 2012 at 11:14 by alexan_e (added function comment)

Tags: None Add / Edit Tags
Categories
AVR

Comments

  1. arthur0's Avatar
    Hi and sorry for misbehaving. Didn't mean to do evil, just experimented a bit (you know what I'm talking about)...
    As a token of respect, here's my version of the above (equivalent except for leading zeros):
    Code C - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    /* Format DWORD to ASCII returning the string's length.
    Note: resulting text buffer must be able to hold at least 10 chars. */
    static uint8 _itoa_rev(uint32 n, char *str, uint8 maxLen)
    {
        register sint8 i;
     
        for(i=maxLen-1; i>=0 && n!=0; i--)
        {
            str[i] = n % 10 + '0';  // take one digit at a time
            n /= 10;
        }
     
        return (maxLen-1 - i);
    }/* _itoa_rev() */
    Not sure if it's more efficient, but I find it easier to read.
    Regards,
    Arthur