如何从Powershell中的字符串转换为UInt64?字符串到数字的转换

如何从Powershell中的字符串转换为UInt64?字符串到数字的转换,powershell,type-conversion,powershell-5.0,Powershell,Type Conversion,Powershell 5.0,考虑以下Powershell代码段: [Uint64] $Memory = 1GB [string] $MemoryFromString = "1GB" [Uint64] $ConvertedMemory = [Convert]::ToUInt64($MemoryFromString) 第三行出现故障,原因是: Exception calling "ToUInt64" with "1" argument(s): "Input string was not in a correct format

考虑以下Powershell代码段:

[Uint64] $Memory = 1GB
[string] $MemoryFromString = "1GB"
[Uint64] $ConvertedMemory = [Convert]::ToUInt64($MemoryFromString)
第三行出现故障,原因是:

Exception calling "ToUInt64" with "1" argument(s): "Input string was not in a correct format."
At line:1 char:1
+ [Uint64]$ConvertedMemory = [Convert]::ToUInt64($MemoryFromString)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException
如果我检查
$Memory
的内容:

PS C:\> $Memory
1073741824
那很好


那么,如何在Powershell中将值“1GB”从字符串转换为UInt64?

您的问题是
ToUint64
不理解Powershell语法。你可以通过做以下事情来解决这个问题:

($MemoryFromString / 1GB) * 1GB
由于
$MemoryFromString
将在除法之前转换其数值

这是因为在除法时,Powershell尝试使用其规则将字符串转换为数字,而不是烘焙到
ToUInt64
中的.Net规则。作为转换的一部分,如果发现
GB
后缀,并应用它的规则将
“1GB”
字符串扩展为
1073741824

编辑:或者正如佩瑟拉指出的,您可以执行以下操作:

($MemoryFromString / 1)
补充:

只有结果变量(
[uint64]$ConvertedMemory
=…)的类型约束才能确保将
($MemoryFromString/1)
转换为
[uint64]
[System.uint64]

表达式
$MemoryFromString/1
的结果实际上是类型
[int]
[System.Int32]
):

因此,要确保表达式本身返回一个
[uint64]
实例,必须使用强制转换:

请注意计算周围所需的
(…)
,否则
[uint64]
强制转换将仅适用于
'1gb'
(因此失败)。
或者,
('1gb'/[uint64]1)
也可以工作

注:

  • '1gb'-0
    也会起作用
  • 但是不是
    '1gb'*1'
    (实际上是一个无操作)或
    '1gb'+0
    (结果是字符串
    '1gb0'
    ,因为带有字符串类型LHS的操作符
    *
    +
    执行字符串操作(分别是复制和串联)

PowerShell中的自动字符串到数字转换和数字文字: 当PowerShell执行隐式数字转换时,包括在源代码中执行混合数字类型计算和解析数字文本时,它会方便地自动选择一个“大”到足以容纳结果的数字类型

隐式字符串到数字的转换中,PowerShell可以方便地识别与源代码中数字文本支持的格式相同的

  • 数字基前缀(仅限整数):
    0x
    用于十六进制整数,而
    0b
    用于二进制整数(PowerShell[Core]7.0+)

  • 数字类型后缀
    L
    表示
    [long]
    [System.Int64]
    ),和
    [decimal]
    表示
    [System.decimal]
    );e、 例如,
    '1L'-0
    产生一个
    [long]

    请注意,C#使用
    M
    代替
    D
    ,并使用
    D
    指定
    [System.Double]
    ;此外,C#还支持几个附加后缀

    • PowerShell[Core]6.2+现在支持附加后缀:
      Y
      [sbyte]
      )、
      UY
      [byte]
      )、
      S
      [int16]
      )、
      US
      [uint16]
      )、
      U
      [uint32]
      )或
      [uint24]
      ),和
      UL
      [uint64]

    • PowerShell[Core]7.0+另外支持后缀
      n
      [bigint]

    • 您可以通过官方帮助主题关注未来的发展(如果有)

  • 浮点表示法,如
    1.23
    (仅限十进制);请注意,PowerShell仅将
    识别为小数点,而与当前区域性无关

  • 指数表示法(仅限十进制);e、 例如,
    '1.0e3'-1
    产生
    999

  • 它自己的二进制乘法器后缀
    kb
    mb
    gb
    tb
    pb
    (对于乘法器
    [math]::pow(2,10)
    =
    1024
    [math]::pow(2,20)
    =
    =
    1048576
    ,…);e、 例如,
    '1kb'-1
    产生
    1023
    ;请注意,这些后缀是特定于PowerShell的,因此.NET framework编号解析方法无法识别它们

数字转换规则非常复杂,但这里有一些关键点:

这是基于我自己的实验。如果我错了,一定要告诉我。
类型由其PS类型加速器表示,并映射到.NET类型,如下所示:
[int]
<代码>[System.Int32]

[long]
<代码>[System.Int64]
[decimal]
<代码>[System.Decimal]
[float]
<代码>[System.Single]
[double]
<代码>[System.Double]

  • PowerShell从不自动选择无符号整数类型

    • 注意:在PowerShell[Core]6.2+中,您可以使用类型后缀
      US
      U
      UL
      (见上文)强制将其作为无符号类型(正数)进行处理;e、 例如,
      0xFFFFFFFFFFFFFFU
    • 对于十六进制数字文字,这可能是意外的;e、 例如,
      [uint32]0xffffffff
      失败,因为
      0xffffffff
      首先被隐式转换为有符号类型
      [int32]
      ,这会产生
      -1
      ,作为有符号值,不能转换为无符号类型
      [uint32]
    • 解决办法: <
      PS> ('1gb' / 1).GetType().FullName
      System.Int32
      
      PS> ([uint64] ('1gb' / 1)).GetType().FullName
      System.Int64