Using System.Math and System.Convert to do some basic stuff in Powershell
So I was getting a large number back from a Win32_LogicalDisk query and I didn’t want to say there was 135.261981964111Gb free. I wanted it to say 135.2 Gb free, or something of the sort.
PS>
PS> $cdrive = Get-WMIObject -class win32_logicaldisk | where {$_.DeviceID -match "C:"}
PS> $cdrive.Freespace
145236447232
PS> $cdrivegb = $cdrive.Freespace/1gb
PS> $cdrivegb
135.261981964111
PS>
So using the Round function isn’t too hard to use.
PS> $cdrivegb = [math]::Round($cdrive.Freespace/1gb,2)
PS> $cdrivegb
135.26
PS>
Perfect…. Just what I wanted. Now I have a number that looks like I want.
PS> $cdrivegb = [math]::Round($cdrive.Freespace/1gb,3)
PS> $cdrivegb
135.262
PS> $cdrivegb = [math]::Round($cdrive.Freespace/1gb,5)
135.26198
PS>
As you can see the 2 parameters and syntax are Round(Number to be rounded, digits to round to).
Lets explore [math] a bit more….
You can also call System.Math like this …
PS> $cdrivegb = [system.math]::Round($cdrive.Freespace/1gb,3)
PS> $cdrivegb
135.262
Lets look at how System.Math.Round handles Single vs. Double vs. UInt64 vs. UInt32 vs. Decimal….
Single
Double
Int16 (Short)
Int32 (Integer)
Int64 (Long)
UInt32 These are for unsigned 32bit integers
UInt64 These are for unsigned 64bit integers
Decimal
See here for the Methods and Properties of all the System.Math.Class
Lets also look at System.Convert which will give us the ability to change types from one to another.
See here for the MS Type Conversion Tables…
See here for the MS Conversion Summary
PS> $cdrive
DeviceID : C:
DriveType : 3
ProviderName :
FreeSpace : 145236447232
Size : 200046518272
VolumeName : C Drive
PS> $c = $cdrive.Freespace
PS> $c | gm
TypeName: System.UInt64
Output Truncated…
PS>
PS> $c
145236447232
At this point $c = 145236447232 and its Type is a System.UInt64 (unsigned 64 bit integer).
What if we wanted to make that into a Type:System.String
PS>
PS> $c_string = [Convert]::ToString($c)
PS> $c_string
145236447232
PS> $c_string | gm
TypeName: System.String
Output Truncated…
PS>
So using [System.Convert] we were able to change that long number into a String.
But now that it is a Type:String it is NOT a number anymore…. Looks like you can not do math on a Type:String.
PS> $c_string
145236447232
PS> $c_string+1
1452364472321
PS>
You can do math with Type:UInt64
PS> $c
14523644722
PS> $c+1
14523644723
PS>
You can also do math with Type:Decimal. $c is still an UInt64
PS> $c_decimal = [convert]::ToDecimal($c)
PS> $c_decimal
PS>
Lets review our the variables we have already setup.
PS> $c | gm
TypeName: System.UInt64
Output Truncated…
PS> $c
145236303872
PS> $c_decimal | gm
TypeName: System.Decimal
Output Truncated…
PS> $c_decimal
145236303872
Here are a few basic arithmetic operations
PS>
PS> $c_decimal*10
1452363038720
PS\> $c_decimal*15
2178544558080
PS> $c_decimal
145236303872
PS> $c_decimal+1
145236303873
PS\> $c_decimal+1,222,333,444,555,666
Cannot convert "System.Object[]" to "System.Decimal".
At line:1 char:12
+ $c_decimal+1 <<<< ,222,333,444,555,666 PS> $c_decimal+1222333444555666
1222478680859538
PS> $c_decimal*32513413421341
4722127991577844645732352
PS> $c_decimal*32513413421341351341341342123124235134
Cannot convert value "3.25134134213413E+37" to type "System.Decimal". Error: "Value was either too large or too small f
or a Decimal."
At line:1 char:12
+ $c_decimal*3 <<<<>
PS> [int64]$c_d ecimal*32513413421341351341341342123124235134
4.7221279915779E+48
PS>
PS> 2*2
4
PS>10*10
100
PS>13*13
169
Here we do some multiplication with both the $c_decimal Type:Decimal and $c Type:UInt64. Good we get the same results eh….
PS> $c_decimal*13
1888071950336
PS> $c*13
1888071950336
OK, so lets so more with [System.Math].
Square Root anyone?
PS> $cmath = [System.Math]::Sqrt($c)
PS> $cmath
380913.354557175
PS>
So, I’m wondering how PS interprets numbers that I enter in. I’m checking out
http://en.wikipedia.org/wiki/Integer_(computer_science)#Common_integral_data_types
in order to figure out more about the different number types.
Check this out, wiki says the high mark of Int64 is +9,223,372,036,854,775,807 and the high mark of Int32 is +4,294,967,295. Lets add a 1,000 over the Int64 high mark.
PS> $num
PS>
PS> $num = 9,223,372,036,854,775,807,000
PS> $num | gm
TypeName: System.Int32
Output Truncated…
PS>
HUH ? That number is larger than a Int64… Why is it being classified as an Int32? Ok, PS doesn’t like the thousands mark comma.
PS> $num
9
223
372
36
854
775
807
0
PS> $num = 9223372036854775807000
PS> $num | gm
TypeName: System.Decimal
Output Truncated…
PS>
Lets get rid of the extra 1,000 and present PS with the highest possible Int64 number, then one higher.
PS> $num
9223372036854775807000
PS>
PS> $num = 9223372036854775807
PS> $num | gm
TypeName: System.Int64
Output Truncated…
PS>
PS>$num = 9223372036854775808
$num | gm
TypeName: System.Decimal
Output Truncated…
PS>
You can specify the type of variable if you want … as long as it fits in the Type you specify….
PS> [double] $num1 = 12345678
PS> $num1
12345678
PS> $num1 | gm
TypeName: System.Double
Output Truncated…
PS>
Normally this would create an Int32 Type variable.
PS> $num2 = 12345678
PS> $num2 | gm
TypeName: System.Int32
Output Truncated…
PS>
Lets create an Int32 variable that breaks the Int32 high limit and see the error.
PS> [Int32] $num32 = 42949672959
Cannot convert value "42949672959" to type "System.Int32". Error: "Value was either too large or too small for an Int32."
At line:1 char:15
+ [Int32] $num32 <<<< = 42949672959
PS>
Need to use PI or e.
PS>
PS> $pi = [math]::Pi
PS> $pi
3.14159265358979
PS> $pi | gm
TypeName: System.Double
Output Truncated…
PS>
PS>
PS> $e = [System.Math]::E
PS> $e
2.71828182845905
PS> $e | gm
TypeName: System.Double
Output Truncated…
PS>
If you have noticed Im using [math] and [System.Math]. They can be used interchangeably. Same with [Convert] and [system.convert]. You probably know that PS is almost never case sensitive.
Thats enough for now. Thanks for playing in the sandbox with me.
No comments:
Post a Comment