Understanding a Hex conversion to boolean

I’m using RS-485 coms to send a Hex string containing 16 input values to XOJO. Im trying to convert the Hex string into an array representing the binary values converted to boolean. I’m stumbling on the conversion from decimal to boolean to fill the array.

Public Sub ProcessInputDataRecieved(hexString as string)
  
  Const SIZE As Integer = 16
  
  // Convert the hex string to a numeric value
  Dim hexValue As UInt16
  hexValue = Val("&h" + hexString)
  
  // Convert the numeric value to an array of boolean values representing each input state
  Var inputArray(SIZE-1) As Boolean // Corrected array size
  For i As Integer = 0 To SIZE - 1
    inputArray(i) = (hexValue And (1 << i)) <> 0 // Problem is here!!!!
  Next
  
  
End Sub

I think you may need a BitWise operator here, rather than a logical And.

https://documentation.xojo.com/api/language/bitwise.html#bitwise

Might this work:

// Convert the hex string to a numeric value
Dim binValue As String = Bin(Val("&h" + hexString))


// Convert the binary string to an array of boolean values representing each input state
Var inputArray(SIZE-1) As Boolean
For i As Integer = 0 To SIZE - 1
  inputArray(i) = (Mid(binValue, i+1, 1) = "1")
Next
1 Like

Unless this is part of the new API (and I don’t think it is), Xojo doesn’t support the C style bit shift operator “<<”.

You have to use Bitwise.ShiftLeft and Bitwise.ShiftRight.

2 Likes

The problem with this code is that you’re not evaluating a single byte, but the entire value (less the leading byte). It won’t possibly zero until the end of the loop.

I just created an Issue 72694 requesting a new documentation section listing and describing all the operators in Xojo.

1 Like
    Dim data As MemoryBlock = DecodeHex(theString)
    Dim b1 As Boolean = data.BooleanValue(0)

?

I see Tim. I’ve been working with C++ for Arduino so, hexValue And (1 << i) performs a bitwise AND operation between hexValue and the result of the left shift operation. Not an XOJO operation I guess.

Keeping it simple

Function HexToBoolArray(hexChar As String) As boolean()
// return passed hex character as an array of booleans
select case (hexChar.Trim)
  
case "0"
  Return array(false, false, false, false, false, false, false, false, _
  false, false, false, false, false, false, false, false)
case "1"
  Return array(false, false, false, false, false, false, false, false, _
  false, false, false, false, false, false, false, true)
case "2"
  Return array(false, false, false, false, false, false, false, false, _
  false, false, false, false, false, false, true, false)
case "3"
  Return array(false, false, false, false, false, false, false, false, _
  false, false, false, false, false, false, true, true)
case "4"
  Return array(false, false, false, false, false, false, false, false, _
  false, false, false, false, false, true, false, false)
case "5"
  Return array(false, false, false, false, false, false, false, false, _
  false, false, false, false, false, true, false, true)
  
  'so on and so forth
  
case "F"
  Return array(true, true, true, true, true, true, true, true, _
  true, true, true, true, true, true, true, true)
  
case else
  var err as new OutOfBoundsException
  raise err
end select

Keep in mind that it is a pointer to the array that is returned from the function, with a very limited scope. If you want to store the array for later you will need to copy to an array with sufficient scope, or modify the function to pass an array in by reference.

OMG, Not like that. :crazy_face:

3 Likes

Public Function BitToBoolean(uIntVal As UInt64, bit As Integer) As Boolean
  // Returns any bit of uIntVal as a Boolean
  If bit<0 Or bit>63 Then Raise New RuntimeException("Invalid bit number", 0)
  Var mask As Uint64 = 2 ^ bit
  uIntVal = uIntVal And mask
  Return uIntVal <> 0
End Function


// Test:

Sub Opening() Handles Opening

  Var i, v As Integer
  // Just convert your hex value to an integer and consult its bits as you wish later
  v = &b1000100110011101
  
  For i = 0 to 15
    System.DebugLog If(BitToBoolean(v,i), "True", "False") // show any bit of v
  Next
  
  break
  
// Results as:
//
// True
// False
// True
// True
// True
// False
// False
// True
// True
// False
// False
// True
// False
// False
// False
// True


End Sub
2 Likes

Let’s add some bit manipulation to the pack

Public Function SetBitTo(uIntVal As UInt64, bit As Integer, bitVal As Integer) As UInt64
  // Returns a 64bit Integer equals to uIntVal with bit set as bitVal (0, not 0 = 1)
  Return SetBitTo(uIntVal, bit, bitVal <> 0)
End Function


Public Function SetBitTo(uIntVal As UInt64, bit As Integer, bitVal As Boolean) As UInt64
  // Returns a 64bit Integer equals to uIntVal with bit set as bitVal (true=1, false=0)
  If bit<0 Or bit>63 Then Raise New RuntimeException("Invalid bit number", 0)
  Var mask As Uint64 = 2 ^ bit
  If bitVal Then // set bit to 1
    uIntVal = uIntVal Or mask
  Else // set bit to 0
    mask = -1 Xor Mask
    uIntVal = uIntVal And mask
  End
  Return uIntVal
End Function

So now you can read/manipute bits directly from/into Integers without needing intermediary arrays

2 Likes

My arsenal just expanded. Your approach is sound. Thanks very much for the great info.

1 Like

And for Hex in and out:

image

1 Like