Hex string to Integer convertor

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • GrahamG
    New Member
    • Nov 2006
    • 7

    #1

    Hex string to Integer convertor

    Hi, got the following code working after some effort. But have a question about the recursive code. I works fine but I cannot step through it to see what happens. Is there something that I can do to the code to see the "internal workings" at each recursion?

    question1. It works but I dont get why the line with the hex+1 works correctly catching the 1st character correctly - why?

    question2. Is there a way to eliminate the 2nd calling parameter, the ,int l) in function HextoDec

    question3. xtod can also be substituded for #define xtod, which way is the best?


    Code:
    #define xtod(c) ((c>='0' && c<='9') ? c-'0' : ((c>='A' && c<='F') ? \
                    c-'A'+10 : ((c>='a' && c<='f') ? c-'a'+10 : 0)))

    Code:
    char xtod(char c) {
     if (c>='0' && c<='9') return c-'0';
     if (c>='A' && c<='F') return c-'A'+10;
     if (c>='a' && c<='f') return c-'a'+10;
     return c=0;        // not Hex digit
    }
    
    int HextoDec(char *hex, int l)
    {
    	if (*hex==0) return(l);
    	return HtoDec(hex+1, l*16+xtod(*hex)); // hex+1?
    }
    
    int xstrtoi(char *hex)	  // hex string to integer
    {
    	return HextoDec(hex,0);
    }
    
    xstrtoi("fe6F2"); // works ok
    xstrtoi("0xfe6F2"); //works ok
    xstrtoi("0xfev6F2"); // bombs output fe06f2
  • horace1
    Recognized Expert Top Contributor
    • Nov 2006
    • 1510

    #2
    (1) why you need hex+1
    when you call the function
    xstrtoi("fe6F2" );
    the pointer char *hex points to the character 'f' which is converted
    then when you call
    HextoDec(hex+1, l*16+xtod(*hex) );
    the pointer char *hex points to the character 'e' which is converted
    etc etc

    (2) to eliminate the second parameter you could work backwards down the string
    Code:
    int HextoDec(char *hex)
    {
    	if (*hex==0) return 0;
    	return  HextoDec(hex-1)*16 +  xtod(*hex) ; 
    }
    
    int xstrtoi(char *hex)	  // hex string to integer
    {
    	return HextoDec(hex+strlen(hex)-1);
    }
    (3) #define vers functions.
    In C you can use preprocessor macros to generate inline functions. Although macros appear to be similar to functions they are expanded inline with the code and are therefore more efficient in terms of execution time, i.e. the overheads of parameter passing and function call and return are avoided. Because they generate inline code it makes the program bigger so only use them with very small functions. In C++ you would use inline functions.

    Comment

    • GrahamG
      New Member
      • Nov 2006
      • 7

      #3
      Hi Horace, I really appreciated the response. It didn't occur to me to do it backwards. Thanks again!


      Originally posted by horace1
      (1) why you need hex+1
      when you call the function
      xstrtoi("fe6F2" );
      the pointer char *hex points to the character 'f' which is converted
      then when you call
      HextoDec(hex+1, l*16+xtod(*hex) );
      the pointer char *hex points to the character 'e' which is converted
      etc etc

      (2) to eliminate the second parameter you could work backwards down the string
      Code:
      int HextoDec(char *hex)
      {
      	if (*hex==0) return 0;
      	return  HextoDec(hex-1)*16 +  xtod(*hex) ; 
      }
      
      int xstrtoi(char *hex)	  // hex string to integer
      {
      	return HextoDec(hex+strlen(hex)-1);
      }
      (3) #define vers functions.
      In C you can use preprocessor macros to generate inline functions. Although macros appear to be similar to functions they are expanded inline with the code and are therefore more efficient in terms of execution time, i.e. the overheads of parameter passing and function call and return are avoided. Because they generate inline code it makes the program bigger so only use them with very small functions. In C++ you would use inline functions.

      Comment

      • Kevin Filteau

        #4
        Why not using strtoul ?

        Comment

        • donbock
          Recognized Expert Top Contributor
          • Mar 2008
          • 2427

          #5
          The macro form will malfunction if the parameter has side-effects, for instance
          Code:
          int i = xtod(*s++);
          For this reason, among others, you ought to only use function-like macros when there is no other choice.

          The return value of the xtod function ought to be int, not char. I'm a little surprised you didn't get a compiler warning on lines 2-4.

          The logic in both forms of xtod makes the implicit assumption that the character encodings for digits are contiguous and increasing; and also the same assumptions for the letters A-F and a-f. This assumption is true for ASCII, but is not necessarily true for other encodings (for instance, EBCDIC). ASCII is so ubiquitous that it is not unreasonable to assume its use; but you really ought to be aware that you're doing so. That is, you should realize your xtod functions are not portable. They should be commented accordingly.

          As Kevin Filteau pointed out, the portable solution is to use standard library function strtoul.

          Comment

          Working...