Results 1 to 9 of 9

Thread: Some useful functions for you guys!

  1. #1

    Thread Starter
    Lively Member dubae524's Avatar
    Join Date
    Jun 2001
    Location
    Currently on this Super Star Destroyer being telekinetically strangled to death by Darth Vader
    Posts
    78

    Talking Some useful functions for you guys!

    I have some useful code attached herein.

    Somebody who just read it a few minutes ago called it sh%&^y, but, hey, I'm still a newbie. It converts a decimal string to a hexadecimal string, and vice versa. Perhaps you guys can help me clean it up a bit.
    Attached Files Attached Files
    - Justin Patrick Butler

    Comme je trouve. "As I find."
    - Butler family quote

    Beneficia sumptos procul superant. "The benefits far exceed the costs."
    - Myself

  2. #2
    Lively Member
    Join Date
    May 2000
    Posts
    123
    hey its not too bad ... it is kind of sloppy but its a good start for a newbie.

    its not really useful to other programmers though because there are standard libraries which contain those functions, but its great coding practice for you nonetheless. keep it up!

  3. #3
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Actually there are no functions that do this highlife...

    It's not bad (the formatting went to hell when you copied it to the textfile), here are some comments:

    It is useless to copy the string to the "here" buffer. It only is a stability hazard (because a string can easily be longer than 128 characters) and wastes speed and memory.

    The usual method to traverse a string is this:

    for(char* p = str; *p; p++)
    {
    // (*p) is current character
    }

    Refer to charcters by their real look, the numbers are hard to read. Like: instead of 65, write 'A'. It means exactly the same but is far more readable.

    hexs = 0; (or decs = 0

    Not only does it not work (a change to a parameter value is not seen outside the function), it is a VERY bad idea too. What if the buffer passed to the function is allocated dynamically with malloc or new (or HeapAlloc or whatever)? Once it's a NULL pointer, the memory referred to would be lost! People would get very mad at you.

    The loop in hextodec is inefficient. pow operates on floating point numbers and is slow. It is better to start at the beginning and do this:
    Code:
    int total = 0;
    for(char *p = here; ishexdigit(*p); p++)
    {
      if(isdigit(*p))
        temp = (*p) - '0';
      else if(tolower(*p) >= 'a' && tolower(*p) <= 'f') // saves time
        temp = tolower(*p) - 'a';
      total <<= 4;  // this is the same as "total *= 16;", but faster
      total += temp;
    }
    Whenever this loop encounters a new character, it multiplies the current total with 16 (effectively shifting all hex digits left one position). Then it adds the new rightmost position.

    Memory access is a little faster this way, and the loop body is WAY faster (could be even faster if a char variable temporarily holds the character at (*p), but a good compiler will optimize this disadvantage away)
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  4. #4

    Thread Starter
    Lively Member dubae524's Avatar
    Join Date
    Jun 2001
    Location
    Currently on this Super Star Destroyer being telekinetically strangled to death by Darth Vader
    Posts
    78
    CornedBee, this code just went way over my head. Is it possible you can make it a little simpler? It may make it less efficient, but I may be able to understand it.
    - Justin Patrick Butler

    Comme je trouve. "As I find."
    - Butler family quote

    Beneficia sumptos procul superant. "The benefits far exceed the costs."
    - Myself

  5. #5
    Zaei
    Guest
    CornedBee's code simply loops through the string (the for loop). For each character, it checks to see what value it has (the two if statements), and converts a regular integer. It then multiplies the total by 16(total <<= 4 does this), and adds the value of the character to total.

    Z.

  6. #6
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    I'll try a simpler and well-commented version
    PHP Code:
    #include <ctype.h>

    int atoihex(charstr)
    {
      
    int total 0;  // the total sum
      
    int temp;  // the numerical value of the current character
      // let i be the index to the first character (0)
      // for each loop, check whether the character at position
      // i is a hexadecimal digit using the
      // ishexdigit macro defined in ctype.h
      // then advance to the next character (increment i)
      
    for(int i 0ishexdigit(str[i]); i++)
      {
        if(
    isdigit(str[i]))  // if it is a digit ('0' to '9')
          
    temp str[i] - '0';  // get the numerical value by substracting
          // the ASCII code of '0' from the character, this works because
          // all numbers have adjacent places in the ASCII table
      // if it is not a digit, check whether it is something between
      // 'a' and 'f' or 'A' and 'F' (the letters allowed in hex digits)
      // to make it case insensitive, convert every character to lowercase
      // using the tolower macro from ctype.h
      // if the character was uppercase it's converted, if not nothing
      // happens
      // if the result is within the range 'a' to 'f', enter the if block
        
    else if(tolower(str[i]) >= 'a' && tolower(str[i]) <= 'f'// saves time
      // I had an error here...
      // again: get the numerical value by substracting the ASCII
      // value of the first letter in the series, but because 'a' already
      // means 10 in hex digits, add 10
          
    temp tolower(str[i]) - 'a' 10;
      
    // we just decoded another digit, that means that those we had
      // before are at higher positions -> multiply them by 16 (the radix
      // of hexadecimal numbers)
        
    total *= 16;
      
    // and add the new digit to the total
        
    total += temp;
      }
      
    // return the result
      
    return total;

    Here is a scheme how this function works:
    Code:
    Let's say we pass this string to the function:
    7d3A
    
    First loop: character at position 0
    7d3A
    ^
    ishexdigit returns true, so execute the body:
    isdigit returns true:
    '7' - '0' (55 - 48) = 7, this value is stored in temp
    multiply total with 16:
    0 * 16 = 0
    then add temp:
    0 + 7 = 7
    advance to the next character and repeat:
    7d3A
     ^
    ishexdigit: true
    isdigit: false
    the next if part: tolower returns 'd', which is both >= 'a' and <= 'f'
    therefore, get the numerical value: 'd' - 'a' (100 - 97) + 10 = 13
    then multiply: 7 * 16 = 112
    and add: 112 + 13 = 125
    next digit:
    7d3A
      ^
    ishexdigit: true
    isdigit: true
    '3' - '0' (51 - 48) = 3
    125 * 16 = 2000
    1664 + 3 = 2003
    7d3A
       ^
    ishexdigit: true
    isdigit: false
    tolower: 'a', if applies
    'a' - 'a' (97 - 97) + 10 = 10
    2003 * 16 = 32048
    32048 + 10 = 32058
    7d3A
        ^
    ishexdigit: false
    jump out of loop and return 32058
    you can check that with windows calculator, it is right
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  7. #7

    Thread Starter
    Lively Member dubae524's Avatar
    Join Date
    Jun 2001
    Location
    Currently on this Super Star Destroyer being telekinetically strangled to death by Darth Vader
    Posts
    78
    Thank you so much CornedBee! I did include ctype.h in my program, but the compiler said I still had to define ishexdigit, but since, thanks to you, I understood it so well, it wasn't a problem!

    Thank you! I see the light.

    BTW, this is how I defined ishexdigit:

    #define ishexdigit(i) ((i) >= '0' && (i) <= '9') || (tolower(i) >= 'a' && tolower(i) <= 'f')

    tnx
    - Justin Patrick Butler

    Comme je trouve. "As I find."
    - Butler family quote

    Beneficia sumptos procul superant. "The benefits far exceed the costs."
    - Myself

  8. #8
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    the right name (the one defined in ctype.h) is isxdigit. You can use it or you can use yours. The one in ctype.h is faster because it uses a lookup table. It's only a memory address calculation and one & (AND) operation. Your code needs in worst case 8 comparisons.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  9. #9

    Thread Starter
    Lively Member dubae524's Avatar
    Join Date
    Jun 2001
    Location
    Currently on this Super Star Destroyer being telekinetically strangled to death by Darth Vader
    Posts
    78
    ah ok, thanks.
    - Justin Patrick Butler

    Comme je trouve. "As I find."
    - Butler family quote

    Beneficia sumptos procul superant. "The benefits far exceed the costs."
    - Myself

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width