This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ascii str (multidigit) or ptr to decimal conversion

Hello!

I'm using following formula to convert string to decimal value:

int ptr2dec(char *ptr, unsigned char size)
{
int val = 0;
unsigned char x;

for (x = 0; x < (size - 1); x++)
{
val += *ptr - 0x30; // get next

// skip last ,multiply step
if (x == size)
return (val);

val *= 10; // shift left
ptr++;
}
}

The idea is to extract digit one by one, and
shift whole value left by multyplying it by 10. Posted code may have errors becos i writing it from my head. My code does not have any error checks (eg: character in string, overflow etc.)

I'm searching for things that can optiomize my code. Can you give me some examples of yours str/dec conversion ? I'm also interested in assembler solution.

sorry for broken English
regards
LB

  • This is a horribly simple thing you are doing. In fact, the principles apply to any programming language (not just C).

    Here is your original function with formatting added back in. You may want to learn how to do this yourself on discussion forums. When you don't take the time to make it easy for your peers to quickly review your code (even small pieces like this) you insult them and remove all doubts about your own skill and motivation.

    int ptr2dec(char *ptr, unsigned char size)
    {
    int val = 0;
    unsigned char x;
    
    for (x = 0; x < (size - 1); x++)
      {
      val += *ptr - 0x30; // get next
    
      // skip last ,multiply step
      if (x == size)
        return (val);
    
      val *= 10; // shift left
      ptr++;
      }
    }
    

    There are a number of problems and poor choices with your algorithm.

    1. It FAILS if size is 1.
    2. Testing x == size in the loop is a waste of time. It never happens since x < (size - 1) is the loop condition.
    3. Since the loop has a condition, why not use it to test your escape from the loop?
    4. This algorithm does not test for the null-terminator at the end of the string.
    5. This algorithm does not test the character to make sure it's a digit before the conversion.
    6. When the loop exits, your function DOES NOT return val. Is this REALLY what you want to happen?

    Here is my rendetion of your function:

    unsigned int str2dec (
      char *ptr,
      unsigned char size)
    {
    unsigned int val = 0;
    
    for (; size && *ptr; ptr++, size--)
      {
      if (!isdigit(*ptr)) break;
      val = (val * 10) + *ptr - '0';
      }
    
    return (val);
    }
    

    Since this looks like a homework assignment to me, I'm not obliged to explain much more. If you are trying to learn how to do things, you need to study it yourself anyway.

    Jon


  • This is a horribly simple thing you are doing. In fact, the principles apply to any programming language (not just C).


    Right, i wroted this code only for showing idea, i mentioned that the my code is probably full of errors.


    1. It FAILS if size is 1.
    4. This algorithm does not test for the null-terminator at the end of the string.
    5. This algorithm does not test the character to make sure it's a digit before the conversion.
    6. When the loop exits, your function DOES NOT return val. Is this REALLY what you want to happen?


    This is not matter in this context :)


    2. Testing x == size in the loop is a waste of time. It never happens since x < (size - 1) is the loop condition.


    Another mistake. I was checking index becos when i cycle thru whole value last digit should not be multiplied (we got 12340 instead of 1234 in my example).

    Your code is good looking, and covers all of error checks that i mentioned, but:

    My question is: is there another way to decode chars to decimal without multiply ?

    thanks for reply
    reagrds
    LB

  • My question is: is there another way to decode chars to decimal without multiply ?

    It is important clearly to define what you trying to achieve.

    Actually, you are converting a string of decimal ASCII characters to binary - not decimal.

    Conversion from one number base to another is generically known as radix conversion. It is common computer science problem and has received a great deal of attention over the years. Although there may be a few tricks possible in special cases, I think it is fair to say that radix conversion generally requires either multiplication or division.

  • "My question is: is there another way to decode chars to decimal without multiply?"

    Why do you want to avoid multiplication??

    As Graham says, Radix conversion requires multiplication - just think about the meaning of place value, and you will understand why...

    But, if you also think back to your elementary arithmetic, what is multiplication?
    It's just repeated addition...

  • Actually, there is a faster way than multiplying. However, it relies on good knowledge of the dataset (which is clearly not present in your provided assumptions).

    For example, if you KNOW that you will convert exactly 2 digits each time, you can convert each digit into a 4-bit value and use a 100 byte long lookup table. This could be repeated for each pair of digits depending on whether they represent 1's, 100's, 10000's, or so on. For example:

    1. Get first digit and mask with 0x0F.
    2. Get second digit, shift < 4 and mask with 0xF0.
    3. Combine.
    4. Index into table for value.
    5. Add to sum.
    6. Repeat.

    However, this may actually take longer than the x10 multiply. It will certainly take more memory and be more complex. It may even be so complex that undiscovered bugs are easily introduced. Either way, I wouldn't want to work on an application where that kind of thing was done often.

    Jon