Understanding Numbers in PowerShell
Dr Scripto
Summary: Microsoft Scripting Guy, Ed Wilson, talks about numbers in Windows PowerShell.
Hey, Scripting Guy! One of the things that is frustrating to me with Windows PowerShell is the way that it handles numbers. For example, I want to know the percent of processor utilization for something, and it displays a number that is like fifty million numbers long. What is up with that? Why can’t Windows PowerShell just tell me something useful?
—SP
Hello SP,
Microsoft Scripting Guy, Ed Wilson, is here. Today it is cold and raining outside. I decided to make a cup of red berry tea. It does not have any caffeine, and it seems to be just thing for a cold, rainy morning. I do not mix my own red berry tea—this is one of the teas that I buy already mixed. I still had a nice bag I brought back from Hamburg. Anyway, I am sitting here sipping a nice cup of red berry tea and I came across your email to scripter@microsoft.com. It is perfect because today I am kicking off Numbers Week.
There are many cmdlets and functions built-in to Windows PowerShell that display a formatted number. But there are other interfaces that return the raw number. The reason for this is that I may want to display information to 1, 2, 3, or even 5 decimal places, depending on what I am monitoring. In many cases, I work with the entire raw number so I can get a better view of what exactly might be taking place. For this reason, it makes sense to understand a bit about the types of numbers in Windows PowerShell.
Numeric types
There are many types of numbers in Windows PowerShell. Most of the time, I do not need to know anything about the different types of numbers because Windows PowerShell performs the type conversion behind the scenes. However, a good understanding of the types of numbers can be useful, and it is certainly useful from a troubleshooting perspective. There are actually three numeric types that Windows PowerShell uses:
- Decimal types
- Integral types
- Floating-point types
Decimal types
Decimals are a 128-bit data type. Decimals can be positive or negative, and they are more precise than floating point types. Decimals are commonly used in financial or monetary calculations. A decimal is an instance of the System.Decimal .NET Framework type, and therefore, it has static properties I can use to determine the range. Here is the minimum and maximum range of the decimal numeric type:
PS C:> [decimal]::MinValue
-79228162514264337593543950335
PS C:> [decimal]::MaxValue
79228162514264337593543950335
This range is commonly expressed as (-7.9 x 10^{28} to 7.9 x 10^{28}) / (10^{0 to 28}).
Integral types
Integral types come in the signed and the unsigned variety (except for the char, which is an 16-bit Unicode character). Integers range in size from 8-bit integers to 64-bit integers.
An sbyte is a signed 8-bit integer, and it ranges from -128 to 127. A byte is an unsigned 8-bit integer that ranges from 0 to 255. The following code illustrates this:
PS C:> [byte]::MinValue
0
PS C:> [byte]::MaxValue
255
PS C:> [sbyte]::MinValue
-128
PS C:> [sbyte]::MaxValue
127
A short is a signed 16-bit integer, and a ushort is an unsigned 16-bit integer. To obtain a short, I use the System.Int16 .NET Framework class, and to obtain a ushort, I use System.uInt16. I can use the [int16] and the [uint16] type accelerators for this purpose. The following code illustrates their ranges:
PS C:> [int16]::MinValue
-32768
PS C:> [int16]::MaxValue
32767
PS C:> [uint16]::MinValue
0
PS C:> [uint16]::MaxValue
65535
Int is the default numeric data type in Windows PowerShell. It is a 32-bit signed integer. The .NET Framework class is System.Int32. Because it is the default numeric data type, I can use [int32] or [int]. There is also an unsigned 32-bit integer. It is the System.uint32 .NET Framework type. I can use [uint32] to create an unsigned 32-bit integer. The ranges of these numbers are shown here:
PS C:> [int32]::MinValue
-2147483648
PS C:> [int32]::MaxValue
2147483647
PS C:> [int]::MaxValue
2147483647
PS C:> [uint32]::MinValue
0
PS C:> [uint32]::MaxValue
4294967295
A long is a signed 64-bit integer and a ulong is an unsigned 64-bit integer. The .NET Framework classes are System.Int64 and System.uInt64. I can therefore use [int64] or [uint64] to create the long or the ulong data types. The following code illustrates the ranges of the long and ulong:
PS C:> [int64]::MinValue
-9223372036854775808
PS C:> [int64]::MaxValue
9223372036854775807
PS C:> [uint64]::MinValue
0
PS C:> [uint64]::MaxValue
18446744073709551615
Floating-point types
There are two floating-point types that Windows PowerShell uses: the float and the double. The float uses seven digits of precision and the double uses 15–16 digits of precision. The float type is an instance of the System.Single .NET Framework value type, and the double is an instance of the System.Double type. I can therefore use [single] and [double] to constrain numbers to these types. The following code illustrates their minimum and maximum values:
PS C:> [single]::MinValue
-3.402823E+38
PS C:> [single]::MaxValue
3.402823E+38
PS C:> [double]::MinValue
-1.79769313486232E+308
PS C:> [double]::MaxValue
1.79769313486232E+308
The following table summarizes the numeric value types, their ranges, sizes, and .NET Framework types.
Type | Range | Size or Precision | .NET Framework type |
Decimal | (-7.9 x 10^{28} to 7.9 x 10^{28}) / (10^{0 to 28}) | 28 – 29 significant digits | System.Decimal |
Sbyte | -128 to 127 | Signed 8-bit | System.Sbyte |
Byte | 0 to 255 | Unsigned 8-bit | System.Byte |
Char | U+0000 to U+ffff | Unicode 16-bit | System.Char |
Short | -32,768 to 32,767 | Signed 16-bit | System.Int16 |
Ushort | 0 to 65,535 | Unsigned 16-bit | System.Uint16 |
Int | -2,147,483,648 to 2,147,483,647 | Signed 32 bit | System.Int32 |
Uint | 0 to 4,294,967,295 | Unsigned 32-bit | System.Uint32 |
Long | 9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | Singed 64-bit | System.Int64 |
Ulong | 0 to 18,446,744,073,709,551,615 | Unsigned 64-bit | System.Uint64 |
Float | ±1.5e−45 to ±3.4e38 | 7 digits | System.Single |
Double | ±5.0e−324 to ±1.7e308 | 15 – 16 digits | System.Double |
That is all there is to using Windows PowerShell to format numbers, SP. Numbers Week will continue tomorrow when I will talk about more cool stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy