Pete Hinchley: Casting Integers in PowerShell

I recently got caught out by a difference in behaviour between .NET and PowerShell when casting integers.

Take the following C# code sample; it initialises an unsigned 16 bit integer with the maximum possible value of 65,535, adds 1, and casts the result as another unsigned 16 bit integer. The result is 0 (the overflow is discarded).

UInt16 max = UInt16.MaxValue;
(UInt16)(max + 1);

Here is the equivalent code in PowerShell:

[uint16]$max = [uint16]::maxvalue
[uint16]($max + 1)

However, in this case, the result is not 0. Instead, the following error is returned: Cannot convert value "65536" to type "System.UInt16". Error: "Value was either too large or too small for a UInt16."

To mirror the C# behaviour in PowerShell, you could try this instead:

[uint16]$max = [uint16]::maxvalue
[uint16]($max + 1 -band 0xffff)

The "binary AND" operation truncates the value to 2 bytes, discarding the overflow before attempting to cast the result, and thereby avoiding the previous error.