Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a PowerShell subtraction convert uint32 values to int32 internally?

When I wanted to script a subtraction involving two [unit32] variables I got the warning "Error: "Value was either too large or too small for an Int32."

A sample to illustrate what I saw

$v1 = [uint32]([int32]::MaxValue + 1)
$v2 = [uint32]([int32]::MaxValue + 2)
$v2 - $v1

Is this normal behaviour ? And how can I avoid the error ?

like image 286
LucD Avatar asked Mar 27 '11 10:03

LucD


1 Answers

You are right it's a bit strange. But the correct way of writting it, is the following and it works :

PS C:\> $v1 = [uint32]([int32]::MaxValue) + 1
PS C:\> $v2 = [uint32]([int32]::MaxValue) + 2
PS C:\> $v2 -$v1
1

The explanation is that ([int32]::MaxValue + 1) is non sense. If you decompose your first affectation you can see a conversion into a double.

PS C:\> $a = ([int32]::MaxValue + 1)
PS C:\> $a.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Double                                   System.ValueType

The really strange thing is that if you just add a line it works again.

PS C:\> $v1 = [uint32]([int32]::MaxValue + 1)
PS C:\> $v2 = [uint32]([int32]::MaxValue + 2)
PS C:\> $v2 += 1
PS C:\> $v2 - $v1
2

You can investigate such expression with the Cmdlet Trace-Command:

PS C:\> Trace-Command -Name TypeConversion -Expression {[uint32]([int32]::MaxValue + 1)} -PSHost
DÉBOGUER : TypeConversion Information: 0 : Converting "64" to "System.Int32".
DÉBOGUER : TypeConversion Information: 0 :     Result type is assignable from value to convert's type
DÉBOGUER : TypeConversion Information: 0 : Converting "System.Object[]" to "System.Object[]".
DÉBOGUER : TypeConversion Information: 0 :     Result type is assignable from value to convert's type
DÉBOGUER : TypeConversion Information: 0 : Conversion to System.Type
DÉBOGUER : TypeConversion Information: 0 :     Conversion to System.Type
DÉBOGUER : TypeConversion Information: 0 :         Found "System.Int32" in the loaded assemblies.
DÉBOGUER : TypeConversion Information: 0 : Converting "2147483647" to "System.Double".
DÉBOGUER : TypeConversion Information: 0 :     Numeric conversion succeeded.
DÉBOGUER : TypeConversion Information: 0 : Converting "1" to "System.Double".
DÉBOGUER : TypeConversion Information: 0 :     Numeric conversion succeeded.
DÉBOGUER : TypeConversion Information: 0 : Conversion to System.Type
DÉBOGUER : TypeConversion Information: 0 :     Conversion to System.Type
DÉBOGUER : TypeConversion Information: 0 :         Found "System.UInt32" in the loaded assemblies.
DÉBOGUER : TypeConversion Information: 0 : Converting "2147483648" to "System.UInt32".
DÉBOGUER : TypeConversion Information: 0 :     Numeric conversion succeeded.
2147483648

Most of the time Trace-Command give more informations.

JP

like image 154
JPBlanc Avatar answered Sep 25 '22 06:09

JPBlanc