Преобразует ли PowerShell внутренне значение uint32 в int32? - PullRequest
3 голосов
/ 27 марта 2011

Когда я хотел написать сценарий вычитания, включающий две переменные [unit32], я получил предупреждение «Ошибка:« Значение было слишком большим или слишком маленьким для Int32 ».

Образец, иллюстрирующий то, что я видел

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

Это нормальное поведение? И как мне избежать ошибки?

Ответы [ 2 ]

5 голосов
/ 27 марта 2011

Вы правы, это немного странно. Но правильный способ его записи следующий: он работает:

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

Объяснение состоит в том, что ([int32]::MaxValue + 1) не имеет смысла. Если вы разложите свою первую аффектацию, вы увидите преобразование в двойное число.

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

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

Действительно странная вещь в том, что если вы просто добавите строку, она снова заработает.

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

Вы можете исследовать такое выражение с помощью командлета 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

Большую часть времени Trace-Command дают больше информации.

JP

2 голосов
/ 27 марта 2011

Очевидно, что арифметика PowerShell всегда подписана и не конвертируется в следующий больший тип, если это действительно необходимо.В качестве обходного пути вы можете использовать [long] / [Int64]:

PS> [long]$v2-$v1
1

или просто объявить ваши переменные изначально равными [long].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...