Convert BitArray to integer in PowerShell

422 views Asked by At

Summary

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)

Actual Result

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')"

Expected Result

$result variable is populated with the value of the BitArray represented as an integer.

2

There are 2 answers

0
AudioBubble On

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]
0
phuclv On

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