converting the 16 bit data to 8 bit and then reversing it back to 16 bits
Module Module1
Sub Main()
' Original 16-bit data
Dim originalValue As UShort = &HA91
' Split into two 8-bit values
Dim highByte As Byte = CByte((originalValue >> 8) And &HFF)
Dim lowByte As Byte = CByte(originalValue And &HFF)
' Display the split values
Console.WriteLine("High Byte: 0x{0:X2}", highByte)
Console.WriteLine("Low Byte: 0x{0:X2}", lowByte)
' Combine the two 8-bit values back into a 16-bit value
Dim combinedValue As UShort = CUShort((CUShort(highByte) << 8) Or CUShort(lowByte))
' Display the combined value
Console.WriteLine("Combined Value: 0x{0:X3}", combinedValue)
' Check if the original value matches the combined value
If originalValue = combinedValue Then
Console.WriteLine("The values match!")
Else
Console.WriteLine("The values do not match!")
End If
Console.ReadLine()
End Sub
End Module
i am getting 2570 instead of 2705 for hex value of &HA91
It's unclear why one would need to recombine the low byte and high byte. Nonetheless, the following should resolve your issue. Change the following code
From:
' Combine the two 8-bit values back into a 16-bit value
Dim combinedValue As UShort = CUShort((highByte << 8) Or lowByte)
To:
' Combine the two 8-bit values back into a 16-bit value
Dim combinedValue As UShort = (CUShort(highByte) << 8) Or lowByte
Here's the explanation. To understand the issue, let's look at a truth table.
Truth table for conjunction (AND)
p | q | p AND q |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
Truth table for disjunction (OR)
p | q | p OR q |
---|---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
Note: I recommend using the built-in Windows calculator - using the menu to select Programmer mode. To enter a HEX value, click on HEX prior to using the keypad. Likewise, to enter a decimal value, click on DEC prior to using the keypad. As you may already know, to enter a binary value, one clicks on BIN prior to using the keypad.
Let's look at the value &HA91
:
The highByte (ie: most significant byte) value is: 0A
(binary: 0000 1010)
The lowByte (ie: least significant byte) value is: 91
(binary: 1001 0001)
Let's look at some code:
Console.WriteLine($"shifted value: {(highByte << 8).ToString("X8")}")
Result:
shifted value: 0000000A
According to << Operator (Visual Basic):
Result: Integral numeric value. The result of shifting the bit pattern. The data type is the same as that of pattern.
Pattern: Integral numeric expression. The bit pattern to be shifted. The data type must be an integral type (SByte, Byte, Short, UShort, Integer, UInteger, Long, or ULong).
Amount: Numeric expression. The number of bits to shift the bit pattern. The data type must be Integer or widen to Integer.
To prevent shifting by more bits than the result can hold, Visual Basic masks the value of amount with a size mask corresponding to the data type of pattern. The binary AND of these values is used for the shift amount. The size masks are as follows:
Data type of pattern | Size mask (decimal) | Size mask (hexadecimal) |
---|---|---|
SByte, Byte | 7 | &H00000007 |
Short, UShort | 15 | &H0000000F |
If amount is zero, the value of result is identical to the value of pattern.
In the code in the OP, is the following:
Dim originalValue As UShort = &HA91
Dim highByte As Byte = CByte((originalValue >> 8) And &HFF)
...
Dim combinedValue As UShort = CUShort((highByte << 8) Or lowByte)
Let's look at the following: highByte << 8
.
highByte
is a Byte
and a left shift by 8
is being done. According to the documentation, a check is performed.
8
(binary: 1000)Description | |
---|---|
8 | 1000 |
7 | 0111 |
8 AND 7 | 0000 |
As previously stated above: If amount is zero, the value of result is identical to the value of pattern (ie: highByte).
What happens if we do highByte OR lowByte
?
Description | ||
---|---|---|
highByte | 0000 | 1010 |
lowByte | 1001 | 0001 |
highByte OR lowByte | 1001 | 1011 |
highByte OR lowByte
= 1001 1011
= Hexadecimal 9B
.
What happened? One needs to have a UInt16
(or UShort) before shifting the bits left.
According to >> Operator (Visual Basic):
Note that the data types Byte, UShort, UInteger, and ULong are unsigned, so there is no sign bit to propagate. If pattern is of any unsigned type, the vacated positions are always set to zero.
which means:
Dim highByte As Byte = CByte((originalValue >> 8) And &HFF)
can be changed to
Dim highByte As Byte = CByte(originalValue >> 8)