PowerShell 减法是否在内部将 uint32 值转换为 int32?

发布于 2024-10-27 04:10:58 字数 229 浏览 0 评论 0原文

当我想编写涉及两个 [unit32] 变量的减法脚本时,我收到警告“错误:“对于 Int32 来说值太大或太小。”

一个示例来说明我所看到的情况

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

这是正常行为吗? 我怎样才能避免这个错误?

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦里人 2024-11-03 04:10:58

你是对的,这有点奇怪。但正确的写法如下,并且有效:

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

您可以使用 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

大多数情况下 Trace-Command 会提供更多信息。

太平绅士

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

明媚殇 2024-11-03 04:10:58

显然,PowerShell 的算术总是有符号的,并且确实在必要时不会转换为下一个更大的类型。作为解决方法,您可以使用 [long]/[Int64]

PS> [long]$v2-$v1
1

或者最初将变量声明为 [long]

Apparently PowerShell's arithmetic is always signed and does not convert into the next larger type if necessary, indeed. As a workaround you can use [long]/[Int64]:

PS> [long]$v2-$v1
1

Or just declare your variables to be [long] initially.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文