Shop OBEX P1 Docs P2 Docs Learn Events
Convert hex string to decimal — Parallax Forums

Convert hex string to decimal

CRST1CRST1 Posts: 103
edited 2014-06-30 10:29 in Propeller 1
Hi, I have been searching all over and can't find the answer. Maybe I am missing something but here goes. I have a serial imput from an xbee. In the string it has the value of the adc channel as a hex string like 02F1 and CR . I can't figure how to convert the hex string to a decimal long variable. I have found the string to dec but I don't think that will work with hex strings will it?
Thanks for any help.

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2014-06-30 05:02
    Check the Numbers object, specifically the FromStr method.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-06-30 05:10
    CRST1 wrote: »
    Hi, I have been searching all over and can't find the answer. Maybe I am missing something but here goes. I have a serial imput from an xbee. In the string it has the value of the adc channel as a hex string like 02F1 and CR . I can't figure how to convert the hex string to a decimal long variable. I have found the string to dec but I don't think that will work with hex strings will it?
    Thanks for any help.

    Sometimes we can spend far more time trying to find the solution to a problem rather than solving it. In this case solving is very easy, starting with an initial result of zero, repeat 4 times or until a CR is detected - shift result left 4 bits (hex shift), subtract $30 from the next character and if the result > 9 then subtract 7 and add this to the result - after all this you will have the number.
  • CRST1CRST1 Posts: 103
    edited 2014-06-30 05:29
    Thank you, I will try the shift method. The information in the numbers object is confusing to me. It doesn't show anything about hex string just dec string so I wasn't sure if it would.
  • CRST1CRST1 Posts: 103
    edited 2014-06-30 05:44
    Peter,
    I think I must be brain dead. I'm still a little confused with the shift method. If I have a string of 02F1 could you show me a code example of what you described? I can't seem to get it into my head.
  • CRST1CRST1 Posts: 103
    edited 2014-06-30 05:50
    Ok, I might have it. Was the shift just to get rid of the first 0? So the 2 would be equal to $32 and subtract $30 you end up with 2, correct? But in this case it would be 2 * 256 correct?
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-06-30 06:03
    CRST1 wrote: »
    Ok, I might have it. Was the shift just to get rid of the first 0? So the 2 would be equal to $32 and subtract $30 you end up with 2, correct? But in this case it would be 2 * 256 correct?

    RESULT = 0
    REPEAT WHILE CH <> $0D
    RESULT = RESULT <<4 (*16 or shift what we have at this point to the left one nibble (hex char) place )
    N = CH-$30 (assuming we read the next character from the buffer)
    IF N > 9 THEN N = N-7 ( this converts an ASCII 0-9 to 0..9 or an A-F (>9 after subtract) to $0A..$0F )
    RESULT = RESULT + N ( since the right most nibble is zero because it has already been shift left 4 place all we need to do is insert the next nibble with a + )


    So assuming we are converting 012F<cr> :
    RESULT = 0
    RESULT = 0 <<4
    "0" - $30 --> 0 and it's not > 9
    RESULT = 0+0 = 0
    next character
    RESULT = 0 << 4 = 0
    "1" - $30 --> 1 and it's not > 9
    RESULT = 0+1 = 1
    next character
    RESULT = 1 <<4 = $10
    "2" - $30 --> 2 and it's not > 9
    RESULT = $10+2 = $12
    next character
    RESULT = $12 << 4 = $120
    "F" - $30 --> $16 and it's > 9 so subtract another 7 ---> $0F
    RESULT = $120 + $0F = $12F
    next character $0D terminates loop with RESULT = $012F
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-06-30 06:06
    pub gethex(str) | char
      repeat while byte[str] == " "
        str++
      repeat
        char := byte[str++]
        case char
          "0".."9": result := (result << 4) + char - "0"
          "a".."f": result := (result << 4) + char - "a" + 10
          "A".."F": result := (result << 4) + char - "A" + 10
          other   : quit
    
  • CRST1CRST1 Posts: 103
    edited 2014-06-30 06:19
    OK, thank you very much. With the help I think I got my head wraped around it now. I do have it working now that I can see it.

    Thank you
  • lonesocklonesock Posts: 917
    edited 2014-06-30 10:17
    I like the 'lookdown' method for this:
    PUB HToI( strptr ) : int | c
    {{
      * Converts a hexadecimal string to an integer
      > strptr : pointer to a string with a hexadecimal number in it
      < Returns the integer, or 0 if no base-16 digits were found.
    
      e.g. i := HToI( string( "2A" ) )  ' returns 42 
    }}
      repeat while c := lookdown( byte[strptr++] : "a".."f","0".."9","A".."F" )
        ' we got something new
        int <<= 4
        int |= (c + 9) & 15
    
    This version also handles lower or upper case characters.

    Jonathan
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-06-30 10:29
    The "StrToBase" method in Parallax Serial Terminal.spin will do this for any base. You could just add it to whichever serial driver you're using.

    IMO, it's a shame they made it a private method (as they did "RxCheck").
    PRI StrToBase(stringptr, base) : value | chr, index{Converts a zero terminated string representation of a number to a value in the designated base.
    Ignores all non-digit characters (except negative (-) when base is decimal (10)).}
    
    
      value := index := 0
      repeat until ((chr := byte[stringptr][index++]) == 0)
        chr := -15 + --chr & 011111 + 39*(chr > 56)                              'Make "0"-"9","A"-"F","a"-"f" be 0 - 15, others out of range     
        if (chr > -1) and (chr < base)                                              'Accumulate valid values into result; ignore others
          value := value * base + chr                                                  
      if (base == 10) and (byte[stringptr] == "-")                                  'If decimal, address negative sign; ignore otherwise
        value := - value
    
    
    

    IMO, it's a nice bit of code.
Sign In or Register to comment.