To 补充 肖恩的有用答案 https://stackoverflow.com/a/41088625/45375:
这只是结果变量的类型约束([uint64] $ConvertedMemory
= ...) 确保($MemoryFromString / 1)
被转换为[uint64]
([System.UInt64]
).
表达结果$MemoryFromString / 1
实际上是类型[int]
([System.Int32]
):
PS> ('1gb' / 1).GetType().FullName
System.Int32
因此,要保证表达式通过它自己返回一个[uint64]
例如,你必须使用cast:
PS> ([uint64] ('1gb' / 1)).GetType().FullName
System.Int64
Note the required (...)
around the calculation, as the [uint64]
cast would otherwise apply to '1gb'
only (and therefore fail).
Alternatively, ('1gb' / [uint64] 1)
works too.
Note:
-
'1gb' - 0
也会起作用的,
- but not
'1gb' * 1'
(实际上是无操作)或'1gb' + 0
(结果为字符串'1gb0'
),因为运营商*
and +
with a string型LHS执行string操作(分别是复制和串联)。
自动的字符串到数字的转换 and 数字字面量在 PowerShell 中:
当PowerShell执行时隐式数字转换,包括在执行混合数字类型计算和解析源代码中的数字文字时,它方便地自动选择一个“大”足以容纳结果的数字类型.
In 隐式字符串到数字的转换, PowerShell 可以方便地识别与号码支持的格式相同literals在源代码中:
-
number-base prefixes (for integers only): 0x
for 十六进制整数,以及0b
for binary整数(PowerShell [核心] 7.0+)
-
number-type suffixes: L
for [long]
([System.Int64]
), and D
for [decimal]
([System.Decimal]
); e.g., '1L' - 0
yields a [long]
.
Note that C# uses M
instead of D
and instead uses D
to designate [System.Double]
; also, C# supports several additional suffixes.
-
PowerShell [核心] 6.2+现在支持附加后缀: Y
([sbyte]
), UY
([byte]
), S
([int16]
), US
([uint16]
), U
([uint32]
or [uint64]
,按需),以及UL
([uint64]
).
-
PowerShell [核心] 7.0+另外还支持后缀n
([bigint]
)
-
您可以通过官方帮助主题关注未来的发展(如果有),about_数字_文字 https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_numeric_literals.
-
浮点表示如1.23
(decimal仅有的);注意PowerShell 只识别.
作为小数点,无论当前的文化如何.
-
指数表示法 (decimal仅有的);例如。,'1.0e3' - 1
yields 999
.
-
its own 二进制乘数后缀, kb
, mb
, gb
, tb
, pb
(对于乘数[math]::pow(2, 10)
== 1024
, [math]::pow(2, 20)
== 1048576
,...);例如。,'1kb' - 1
yields 1023
;请注意,这些后缀是 PowerShell 特定的,因此 .NET 框架数字解析方法不会not认出他们。
The 数字转换规则很复杂,但这里有一些关键点:
This is based on my own experiments. Do tell me if I'm wrong.
Types are expressed by their PS type accelerators and map onto .NET types as follows:
[int]
... [System.Int32]
[long]
... [System.Int64]
[decimal]
... [System.Decimal]
[float]
... [System.Single]
[double]
... [System.Double]
-
电源外壳从不自动选择unsigned整数类型.
- 注:在PowerShell [核心] 6.2+,您可以使用类型后缀
US
, U
or UL
(见上文)强制处理为无符号类型(正数);例如。,0xffffffffffffffffU
- 这对于十六进制来说可能是意想不到的数字字面量; e.g.,
[uint32] 0xffffffff
fails, 因为0xffffffff
is first- 隐式 - 转换为signed type [int32]
,这产生-1
,其中,作为signed值,然后不能转换为unsigned type [uint32]
.
- Workarounds:
- Append
L
强制解释为[int64]
首先,这会产生预期的正值4294967295
,在这种情况下强制转换为[uint32]
成功了。
- 该技术不适用于上述值
0x7fffffffffffffff
([long]::maxvalue
),但是,在这种情况下您可以使用string转换:[uint64] '0xffffffffffffffff'
-
电源外壳widens根据需要的整数类型:
-
For decimal整数文字/字符串,扩大beyond整数类型到[System.Decimal]
, 进而[Double]
, 如所须;例如。:
-
(2147483648).GetType().Name
yields Int64
,因为该值为[int32]::MaxValue + 1
,因此被隐式扩展为[int64]
.
-
(9223372036854775808).GetType().Name
yields Decimal
,因为该值为[int64]::MaxValue + 1
,因此被隐式扩展为[decimal]
.
-
(79228162514264337593543950336).GetType().Name
yields Double
,因为该值为[decimal]::MaxValue + 1
,因此被隐式扩展为[double]
.
-
For 十六进制(始终是整数)文字/字符串,加宽停止于[int64]
:
-
(0x100000000).gettype().name
yields Int64
,因为该值为[int32]::MaxValue + 1
,因此被隐式扩展为[int64]
.
-
0x10000000000000000
,即[int64]::MaxValue + 1
, does not晋升为[System.Decimal]
由于是十六进制并将其解释为数字fails.
-
注意:上述规则适用于单个文字/字符串,但范围扩大表达式可能会导致扩大到[double]
立即(不考虑[decimal]
) - 见下文。
-
PowerShell 貌似从不自动选择整数类型smaller than [int]
:
-
('1' - 0).GetType().FullName
yields System.Int32
(an [int]
),即使整数1
适合[int16]
甚至[byte]
.
-
计算结果永远不会使用比任一操作数更小的类型:
- Both
1 + [long] 1
and [long] 1 + 1
产量a[long]
(即使结果可以适合更小的类型)。
-
或许出乎意料的是,PowerShell 自动选择浮点 type [double]
对于大于任一操作数类型的计算结果integer类型可以适合,即使结果could适合一个更大的整数 type:
-
([int]::maxvalue + 1).GetType().FullName
yields System.Double
(a [double]
),即使结果适合[long]
整数。
- 但是,如果其中一个操作数是足够大的整数类型,则结果就是该类型:
([int]::maxvalue + [long] 1).GetType().FullName
yields System.Int64
(a [long]
).
-
在计算中至少涉及一种浮点类型总是会导致[double]
,即使与整数类型混合或使用 all-[float]
操作数:
-
1 / 1.0
and 1.0 / 1
and 1 / [float] 1
and [float] 1 / 1
and [float] 1 / [float] 1
全部产生 a[double]
-
Number literals在不使用类型后缀的源代码中:
-
Decimal integer文字被解释为以下类型中能够拟合该值的最小者:[int]
> [long]
> [decimal]
> [double]
(!):
-
1
产生一个[int]
(就像声明的那样,[int]
是最小的自动选择类型)
-
214748364
(1 高于[int]::maxvalue
)产生一个[long]
-
9223372036854775808
(1 高于[long]::maxvalue
)产生一个[decimal]
-
79228162514264337593543950336
(1 高于[decimal]::maxvalue
)产生一个[double]
-
十六进制 integer文字被解释为以下类型中能够拟合该值的最小者:[int]
> [long]
;也就是说,与decimal文字,类型大于[long]
不支持;Caveat: 具有高位设置的值导致negative小数,因为 PowerShell 自动选择signed整数类型:
-
0x1
产生一个[int]
-
0x80000000
产生一个[int]
这是一个negative值,因为高位被设置:-2147483648
, 哪一个是smallest [int]
数,如果考虑符号 ([int]::MinValue
)
-
0x100000000
(1 多于可容纳的[int]
(or [uint32]
)) 产生一个[long]
-
0x10000000000000000
(1 多于可容纳的[long]
(or [uint64]
)) breaks, 因为[long]
是支持的最大类型(“数字常量无效”)。
-
确保十六进制文字结果为positive number:
-
Windows PowerShell:使用类型后缀L
强制解释为[long]
首先,然后(可选)转换为unsigned类型;例如[uint32] 0x80000000L
yields 2147483648
,但请注意,该技术仅适用于0x7fffffffffffffff
, i.e., [long]::maxvalue
;如上所述,使用从string作为解决方法(例如,[uint64] '0xffffffffffffffff'
).
-
PowerShell [核心] 6.2+:使用类型后缀us
, u
, or ul
, 如所须;例如。:0x8000us
-> 32768
([uint16]
), 0x80000000u
-> 2147483648
([uint32]
), 0x8000000000000000ul
-> 9223372036854775808
([uint64]
)
-
Binary integer文字 (PowerShell [Core] 7.0+) 的解释方式与十六进制那些;例如。,0b10000000000000000000000000000000
== 0x80000000
== -2147483648
([int]
)
-
浮点 or 指数表示法文字(仅在decimal代表)是总是被解释为[double]
, 无论多小: