【问题标题】:How do I cast an UInt32 to a (negative) Int32 in PowerShell?如何在 PowerShell 中将 UInt32 转换为(负)Int32?
【发布时间】:2020-12-07 09:18:35
【问题描述】:

我有以下类型的System.UInt32:4.294.967.176(以字节为单位:FFFF FF88)。

我必须将此数字解释为System.Int32 类型的数字,它会是:-120(仍以字节为单位:FFFF FF88)。

在 C 或 C++ 等语言中,简单的类型转换可以解决我的问题,但在 PowerShell 中进行类型转换:

[Int32][UInt32]4294967176

抛出错误:

Cannot convert value "4294967176" to type "System.Int32". Error: "Value was either too large or too small for an
Int32."
At line:1 char:1
+ [Int32][UInt32]4294967176
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastIConvertible

看起来 PowerShell 正在尝试“转换”该值,而不仅仅是强制转换它。那么,如何将System.UInt32 转换为System.Int32,即不更改数据,而是使用另一种解释/表示?

【问题讨论】:

  • 4294967178 在二进制补码中解释时实际上是 0xFFFFFF8A 或 -118。在不编译实际 C# 的情况下,一种方法(从字面上重新解释数据)是 [BitConverter]::ToInt32([BitConverter]::GetBytes([uint32] 4294967178))。通过在某个我不知道的地方利用某种方法可能会有更短的方法;在运行时级别,此强制转换是一条指令,但我认为 PowerShell 中没有直接的代码路径。
  • @JeroenMostert 最后一位是错字,我更正了。当添加 0 作为 ToInt32 的第二个参数(作为起始索引)时,您的解决方案有效。谢谢!

标签: powershell int32 uint32


【解决方案1】:

由于 .Net 数值数据类型支持转换为十六进制等价物,请先将 UInt32 转换为字符串。然后使用System.Convert.ToInt32() 并将十六进制解析为int。像这样,

$u = [UInt32]4294967176
$u.tostring('x')
ffffff88

# Convert hex based value to int
$i =  [convert]::toint32($u.tostring('x'), 16) 

# Check that type is int32
$i.GetType()
IsPublic IsSerial Name                             BaseType
-------- -------- ----                             --------
True     True     Int32                            System.ValueType

# Value    
$i
-120

【讨论】:

  • comments 的解决方案稍微快一些,但在 imo 中并不重要。比较代码:$u = [System.UInt32] 4294967176; (Measure-Command {1..100000 | % {[System.Convert]::ToInt32($u.ToString('x'), 16)}}).Ticks; (Measure-Command {1..100000 | % {[System.BitConverter]::ToInt32([System.BitConverter]::GetBytes($u), 0)}}).Ticks
猜你喜欢
  • 1970-01-01
  • 2015-02-17
  • 1970-01-01
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
  • 2011-11-14
  • 2015-08-20
相关资源
最近更新 更多