about_Numeric_Literals

简短说明

本文介绍 PowerShell 中数值的语法和用法。

长说明

有两种类型的数字文本:整数和实数。 两者都可以具有乘数后缀。

整数文本

整数文本可以采用十进制、十六进制或二进制表示法编写。 十六进制文本的前缀为 0x,二进制文本的前缀为 0b,以将它们与十进制数区分开来。

整数文本可以具有类型后缀和乘数后缀。

后缀 含义 注意
y 有符号的字节数据类型 在 PowerShell 6.2 中添加
uy 无符号的字节数据类型 在 PowerShell 6.2 中添加
s Short 数据类型 在 PowerShell 6.2 中添加
us 无符号的短数据类型 在 PowerShell 6.2 中添加
l 长数据类型
u 无符号的整数或长数据类型 在 PowerShell 6.2 中添加
ul 无符号的长数据类型 在 PowerShell 6.2 中添加
n BigInteger 数据类型 在 PowerShell 7.0 中添加
kb kibibyte (10241) 乘数
mb mebibyte (10242) 乘数
gb 吉吉比特 (10243) 乘数
tb teribyte (10244) 乘数
pb petibyte (10245) 乘数

整数文本的类型取决于其值、类型后缀和数字乘数后缀。

对于没有类型后缀的整数文本:

  • 如果值可以通过 [int] 类型表示,则这就是其类型。
  • 否则,如果值可以通过 [long] 类型表示,则这就是其类型。
  • 否则,如果值可以通过 [decimal] 类型表示,则这就是其类型。
  • 否则,它由 [double] 类型表示。

对于有类型后缀的整数文本:

  • 如果类型后缀为 u,并且值可以由类型 [uint] 表示,则其类型为 [uint]
  • 如果类型后缀为 u,并且值可以由类型 [ulong] 表示,则其类型为 [ulong]
  • 如果其值可以通过指定的类型表示,则这就是其类型。
  • 否则,该文本格式不正确。

真实文本

实际文本只能用十进制表示法编写。 此表示法可以包括小数点后面的小数值和使用指数部分的科学表示法。

指数部分包括一个“e”,后跟一个可选符号 (+/-) 和一个表示指数的数字。 例如,文本值 1e2 等于数值 100。

实数文本可以具有类型后缀和乘数后缀。

后缀 含义
d decimal 数据类型
kb kibibyte (10241) 乘数
mb mebibyte (10242) 乘数
gb 吉吉比特 (10243) 乘数
tb teribyte (10244) 乘数
pb petibyte (10245) 乘数

有两种类型的实数文本:double 和 decimal。 这些都是通过是否存在 decimal-type 后缀来分别指明。 PowerShell 不支持 [float] 值的文字表示形式。 双精度实数文本的类型为 [double]。 十进制实数文本的类型为 [decimal]。 十进制实数文本的小数部分中的尾随零很重要。

如果 [double] 实数文本中 exponent-part 的位数少于支持的最小值,则 [double] 实数文本的值为 0。 如果 [decimal] 实数文本中 exponent-part 的位数少于支持的最小值,则该实数的格式错误。 如果 [double][decimal] 实数文本中 exponent-part 的位数多于支持的最大值,则该文本的格式错误。

注意

该语法允许双实数文本具有 long-type 后缀。 PowerShell 将此案例视为一个整数文本,其值由 [long] 类型表示。 保留此功能是为了向后兼容早期版本的 PowerShell。 但是,不建议程序员使用这种形式的整数文本,因为它们很容易掩盖文本的实际值。 例如,1.2L 具有值 1,1.2345e1L 具有值 12,1.2345e-5L 具有值 0,这些都不明显。

数字乘数

为方便起见,整数和实数文本可以包含一个数字乘数,表示一组常用的 2 的幂中的一个。 数字乘数可以用大写或小写字母的任意组合形式编写。

乘数后缀可以与任何类型后缀结合使用,但在类型后缀之后必须存在。 例如,文本 100gbL 格式不正确,但文本 100Lgb 有效。

如果乘数创建的值超出了后缀指定的数值类型的可能值,则文本格式不正确。 例如,文本 1usgb 格式不正确,因为值 1gb 大于 us 后缀指定的 [ushort] 类型所允许的值。

乘数示例

PS> 1kb
1024

PS> 1.30Dmb
1363148.80

PS> 0x10Gb
17179869184

PS> 1.4e23tb
1.5393162788864E+35

PS> 0x12Lpb
20266198323167232

数字类型加速器

PowerShell 支持以下类型加速器:

加速器 注意 说明
[byte] 字节(无符号)
[sbyte] 字节(有符号)
[Int16] 16 位整数
[short] [int16] 的别名 16 位整数
[UInt16] 16 位整数(无符号)
[ushort] [uint16] 的别名 16 位整数(无符号)
[Int32] 32-bit integer
[int] [int32] 的别名 32-bit integer
[UInt32] 32 位整数(无符号)
[uint] [uint32] 的别名 32 位整数(无符号)
[Int64] 64 位整数
[long] [int64] 的别名 64 位整数
[UInt64] 64 位整数(无符号)
[ulong] [uint64] 的别名 64 位整数(无符号)
[bigint] 请参阅 BigInteger 结构
[single] 单精度浮点
[float] [single] 的别名 单精度浮点
[double] 双精度浮点
[decimal] 128 位浮点

注意

以下类型加速器已添加到 PowerShell 6.2 中:[short][ushort][uint][ulong]

示例

下表包含几个数值文字示例,并列出了其类型和值:

数字 类型
100 Int32 100
100u UInt32 100
100D 小数 100
100l Int64 100
100uL UInt64 100
100us UInt16 100
100uy Byte 100
100y SByte 100
1e2 双精度 100
1.e2 双精度 100
0x1e2 Int32 482
0x1e2L Int64 482
0x1e2D Int32 7725
482D 小数 482
482gb Int64 517543559168
482ngb BigInteger 517543559168
0x1e2lgb Int64 517543559168
0b1011011 Int32 91
0xFFFFs Int16 -1
0xFFFFFFFF Int32 -1
-0xFFFFFFFF Int32 1
0xFFFFFFFFu UInt32 4294967295

使用二进制或十六进制数字

只有在指定了 n 后缀的情况下,过大的二进制或十六进制文字可以返回为 [bigint] 而不是使分析失败。 但是,在偶数 [decimal] 范围上仍遵守符号位:

  • 如果二进制字符串的长度为 8 位的倍数,则最高位被视为符号位。
  • 如果十六进制字符串的长度为 8 的倍数,且第一个数字为 8 或更高,则数字被视为负数。

在二进制和十六进制文本上指定无符号后缀会忽略符号位。 例如,0xFFFFFFFF 返回 -1,但 0xFFFFFFFFu 返回的 [uint]::MaxValue 为 4294967295的。

在 PowerShell 7.1 中,对十六进制文本使用类型后缀现在会返回该类型的有符号值。 例如,在 PowerShell 7.0 中,表达式 0xFFFFs 会返回错误,因为正值对于 [int16] 类型来说太大。 PowerShell 7.1 将此解释为 [int16] 类型的 -1

使用 0 作为文本前缀将绕过此项,并被视为无符号。 例如:0b011111111。 当在 [bigint] 范围内处理文本时,这是必需的,因为不能组合 un 后缀。

还可以使用 - 前缀来使二进制和十六进制文本变无效。 这可能会产生正数,因为允许符号位。

BigInteger 后缀数字接受符号位:

  • BigInteger 后缀十六进制将长度为 8 个字符的任意文本的高位视为符号位。 长度不包括 0x 前缀或任何后缀。
  • BigInteger 后缀二进制接受 96 和 128 个字符的符号位,并在之后的每 8 个字符接受一次。

数字类型转换

当字符串转换为数字时,支持其他十六进制格式指示器。 这些附加格式不能识别为文本。

[int] '0xF' -eq 0xF
[int] '&hF' -eq 0xF
[int] '#F' -eq 0xF
[int] '0b1111' -eq 0b1111
[int] '0b1111' -eq 15

类似于数字文本的命令

任何看起来像有效数字文本的命令都必须使用调用运算符 (&) 来执行,否则它将解释为数字。 具有类似 1usgb 的有效语法的格式不正确的文本将导致以下错误:

PS> 1usgb
At line:1 char:6
+ 1usgb
+      ~
The numeric constant 1usgb is not valid.
+ CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : BadNumericConstant

但是,具有类似 1gbus 的有效语法的格式不正确的文本将解释为标准裸字符串,并且可以在调用命令的上下文中解释为有效的命令名称。

访问数字对象的属性和方法

若要访问数字文本的成员,在某些情况下需要将文本括在括号中。

  • 文本没有小数点
  • 文本在小数点之后没有任何数字
  • 文本没有后缀

例如,下面的示例失败:

PS> 2.GetType().Name
At line:1 char:11
+ 2.GetType().Name
+           ~
An expression was expected after '('.
+ CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ExpectedExpression

以下示例起作用:

PS> 2uL.GetType().Name
UInt64
PS> 1.234.GetType().Name
Double
PS> (2).GetType().Name
Int32

前两个示例无需将文字值括在括号中,因为 PowerShell 分析程序可以确定数字文本结束和 GetType 方法开始的位置。

PowerShell 如何分析数字文本

PowerShell v7.0 更改了对数字文本进行分析的方式,以启用新功能。

分析实数数字文本

如果文本包含小数点或 e 表示法,则文本字符串将分析为实数。

  • 如果存在十进制后缀,则直接进入 [decimal]
  • 否则,分析为 [Double],并将乘数应用于值。 然后检查类型后缀并尝试转换为适当的类型。
  • 如果字符串没有类型后缀,则分析为 [Double]

分析整数数字文本

使用以下步骤分析整数类型文本:

  1. 确定基数格式
    • 对于二进制格式,分析为 [BigInteger]
    • 对于十六进制格式,分析为 [BigInteger] 在值位于 [int][long] 区域中时使用特殊情况来保留原始行为。
    • 如果既不是二进制也不是十六进制,则通常分析为 [BigInteger]
  2. 在尝试任何强制转换之前应用乘数值,以确保可以在不溢出的情况下适当检查类型边界。
  3. 检查类型后缀。
    • 检查类型边界并尝试分析为该类型。
    • 如果未使用后缀,则值按以下顺序进行边界检查,导致第一次成功测试确定了数字的类型。
      • [int]
      • [long]
      • [decimal](仅以 10 为底的文本)
      • [double](仅以 10 为底的文本)
    • 如果值超出十六进制和二进制数的 [long] 范围,则分析将失败。
    • 如果值超出以 10 为底的数字的 [double] 范围,则分析将失败。
    • 必须使用 n 后缀显式写入较高的值,才能将文本分析为 BigInteger

分析大值文本

以前,在强制转换为任何其他类型之前,将更高的整数值分析为双精度值。 这会导致较大的范围中的精度损失。 例如:

PS> [bigint]111111111111111111111111111111111111111111111111111111
111111111111111100905595216014112456735339620444667904

若要避免此问题,必须以字符串的形式写入值,然后将其转换:

PS> [bigint]'111111111111111111111111111111111111111111111111111111'
111111111111111111111111111111111111111111111111111111

在 PowerShell 7.0 中,必须使用 N 后缀。

PS> 111111111111111111111111111111111111111111111111111111n
111111111111111111111111111111111111111111111111111111

此外,应使用小数后缀 D 来表示 [ulong]::MaxValue[decimal]::MaxValue 之间的值,以保持准确性。 如果没有后缀,这些值将使用实数分析模式分析为 [Double]