Reputation:
I'm trying to convert a 32-bit BitArray
into an integer using PowerShell version 7. I've tried the C# way of handling it, but it doesn't work.
Here's my code.
$high = [System.Collections.BitArray]::new(@(0x93e0))
$low = [System.Collections.BitArray]::new(@(0x0004))
$low += $high.LeftShift(16)
# Create an integer array with a length of 1
$result = [int[]]::new(1)
# Copy the BitArray to the integer at index 0
$low.CopyTo($result), 0)
An exception is thrown.
MethodInvocationException: Exception calling "CopyTo" with "2" argument(s): "Destination array was not long enough. Check the destination index, length, and the array's lower bounds. (Parameter 'destinationArray')"
$result
variable is populated with the value of the BitArray
represented as an integer.
Upvotes: 2
Views: 481
Reputation: 41962
You don't need to iterate through the bit array and copy the bits like that. Just Or or Xor the arrays together
$low = [System.Collections.BitArray]::new(@(0x93e0))
$high = [System.Collections.BitArray]::new(@(0x0004))
$tmp = $low.Or($high.LeftShift(16)) # Combine the 2 arrays
$result = [int[]]::new(1)
$low.CopyTo($result, 0)
$result[0]
But if your bit arrays are always 32 bits long then you should use BitVector32
instead. It's recommended in the BitArray remarks:
The BitVector32 class is a structure that provides the same functionality as BitArray, but with faster performance. BitVector32 is faster because it is a value type and therefore allocated on the stack, whereas BitArray is a reference type and, therefore, allocated on the heap.
https://learn.microsoft.com/en-us/dotnet/api/system.collections.bitarray?view=net-5.0#remarks
[Collections.Specialized.BitVector32]$low = 0x93e0
[Collections.Specialized.BitVector32]$high = 0x0004
$low.Data -bor ($high.Data -shl 16)
Of course you can still access each bit in BitVector32
independently
Upvotes: 0
Reputation:
The issue is that I was adding two BitArray
instances together, which caused $low
to become a 64-bit BitArray
.
The correct solution is as follows.
$low = [System.Collections.BitArray]::new(@(0x93e0))
$high = [System.Collections.BitArray]::new(@(0x0004))
$high.LeftShift(16)
# Copy the "upper" 16 bits from $high to $low
16..31 | % { $low.Set($PSItem, $high[$PSItem]) }
# Convert the BitArray (singleton) to an integer array
$result = [int[]]::new(1)
$low.CopyTo($result, 0)
# Print the result
$result[0]
Upvotes: 1