I need a function that takes a value as a byte and a starting position as an integer, and returns a 1 or 0 as an unsigned byte, depending on whether the corresponding bit is 1 or 0.
Example 1:
Decimal 100 is binary 0110 0100. If the starting position (index) is 1 (counting from the left), I expect a return of 1 because 0110 0100.
Example 2:
If the starting position is 0, I expect a return of 0 because 0110 0100.
I also need the same principle applied to a function that takes a byte array.
My current issue is that the functions return the wrong result. The provided position is off by 1. I know this is the error because I tested this up to position 4. I could simply write (pos-1)
to fix it, but maybe you have a better solution anyway.
In the function with the array, there is currently a 204 included in the code because I adapted the function from a C++ solution where it intentionally read beyond the array boundaries without throwing an exception. In debug mode, I kept seeing 204, no matter how often I restarted the PC.
I need this function in VB.NET. Here's my current attempt:
Option Strict On
Module Module1
Sub Main()
Dim result1 As Byte = GetBitByPos(100, 0)
Dim result2 As Byte = GetBitByPos(100, 1)
Dim result3 As Byte = GetBitByPosArray({100}, 0)
Dim result4 As Byte = GetBitByPosArray({100}, 1)
End Sub
Private Function GetBitByPos(value As Byte, pos As Integer) As Byte
Return CByte(value >> (8 - pos Mod 8) And &H1)
End Function
Private Function GetBitByPosArray(buffer As Byte(), pos As Integer) As Byte
If pos \ 8 >= buffer.Length Then
Return CByte(204 >> (8 - pos Mod 8) And &H1)
End If
Return CByte(buffer(pos \ 8) >> (8 - pos Mod 8) And &H1)
End Function
End Module
You need to use 7 because your indices are 0...7. Also adding safety for pos
overflowing the byte or array
Private Function getBitByPos(value As Byte, pos As Integer) As Byte
pos = pos Mod 8
Return CByte((value >> (7 - pos)) And 1)
End Function
Private Function getBitByPosArray(buffer As Byte(), pos As Integer) As Byte
pos = pos Mod (buffer.Length * 8)
Return CByte((buffer(pos \ 8) >> (7 - pos Mod 8)) And 1)
End Function
Testing with
For i = 0 To 7
Console.Write(getBitByPos(100, i))
Next
Console.WriteLine()
For i = 0 To 25
Console.Write(getBitByPos(100, i))
Next
Console.WriteLine()
Dim buffer As Byte() = {100, 255, 0, 85, 170}
For i = 0 To (8 * buffer.Length) - 1
Console.Write(getBitByPosArray(buffer, i))
If ((i + 1) Mod 8 = 0) And i < (8 * buffer.Length) - 1 Then Console.Write("-")
Next
Console.WriteLine()
For i = 0 To 50
Console.Write(getBitByPosArray(buffer, i))
If ((i + 1) Mod 8 = 0) And i < 100 Then Console.Write("-")
Next
outputs
01100100
01100100011001000110010001
01100100-11111111-00000000-01010101-10101010
01100100-11111111-00000000-01010101-10101010-01100100-111