Welcome PowerShell User! This recipe is just one of the hundreds of useful resources contained in the PowerShell Cookbook.

If you own the book already, login here to get free, online, searchable access to the entire book's content.

If not, the Windows PowerShell Cookbook is available at Amazon, or any of your other favourite book retailers. If you want to see what the PowerShell Cookbook has to offer, enjoy this free 90 page e-book sample: "The Windows PowerShell Interactive Shell".

6.2 Perform Complex Arithmetic

Problem

You want to use PowerShell to calculate more complex or advanced mathematical results.

Solution

PowerShell supports more advanced mathematical tasks primarily through its support for the System.Math class in the .NET Framework.

To find the absolute value of a number, use the [Math]::Abs() method:

PS > [Math]::Abs(-10.6)
10.6

To find the power (such as the square or the cube) of a number, use the [Math]::Pow() method. In this case, the method is finding 123 squared:

PS > [Math]::Pow(123, 2)
15129

To find the square root of a number, use the [Math]::Sqrt() method:

PS > [Math]::Sqrt(100)
10

To find the sine, cosine, or tangent of an angle (given in radians), use the [Math]::Sin(), [Math]::Cos(), or [Math]::Tan() method:

PS > [Math]::Sin( [Math]::PI / 2 )
1

To find the angle (given in radians) of a sine, cosine, or tangent value, use the [Math]::ASin(), [Math]::ACos(), or [Math]::ATan() method:

PS > [Math]::ASin(1)
1.5707963267949

See Recipe 3.12 to learn how to find out what other features the System.Math class provides.

Discussion

Once you start working with the System.Math class, it may seem as though its designers left out significant pieces of functionality. The class supports the square root of a number, but doesn’t support other roots (such as the cube root). It supports sine, cosine, and tangent (and their inverses) in radians, but not in the more commonly used measure of degrees.

Working with any root

To determine any root (such as the cube root) of a number, you can use the function given in Example 6-1.

Example 6-1. A root function and some example calculations
PS > function root($number, $root) { [Math]::Pow($number, 1 / $root) }
PS > root 64 3
4
PS > root 25 5
1.90365393871588
PS > [Math]::Pow(1.90365393871588, 5)
25.0000000000001
PS > [Math]::Pow( $(root 25 5), 5)
25

This function applies the mathematical fact that the square root of a number is the same as raising that number to the power of 1/2, the cube of a number is the same as raising it to the power of 1/3, etc.

The example also illustrates a very important point about math on computers. When you use this function (or anything else that manipulates floating-point numbers), always be aware that the results of floating-point answers are only ever approximations of the actual result. If you combine multiple calculations in the same statement (or store intermediate results into variables), programming and scripting languages can sometimes keep an accurate answer (such as in the second [Math]::Pow() attempt), but that exception is rare.

Some mathematical systems avoid this problem by working with equations and calculations as symbols (and not numbers). Like humans, these systems know that taking the square of a number that you just took the square root of gives you the original number right back—so they don’t actually have to do either of those operations. These systems, however, are extremely specialized and usually very expensive.

Working with degrees instead of radians

Converting radians (the way that mathematicians commonly measure angles) to degrees (the way that most people commonly measure angles) is much more straightforward than the root function. A circle has 2 * Pi radians if you measure in radians, and 360 degrees if you measure in degrees. That gives the following two functions:

function Convert-RadiansToDegrees($angle) { $angle / (2 * [Math]::Pi) * 360 }
function Convert-DegreesToRadians($angle) { $angle / 360 * (2 * [Math]::Pi) }

and their usage:

PS > Convert-RadiansToDegrees ([Math]::Pi)
180
PS > Convert-RadiansToDegrees ([Math]::Pi / 2)
90
PS > Convert-DegreesToRadians 360
6.28318530717959
PS > Convert-DegreesToRadians 45
0.785398163397448
PS > [Math]::Tan( (Convert-DegreesToRadians 45) )
1

Working with large numbers

In addition to its support for all of the standard .NET data types (bytes, integers, floats, and decimals), PowerShell also lets you work with extremely large numbers that these standard data types can’t handle:

PS > [Math]::Pow(12345, 123)
Infinity

PS > [BigInt]::Pow(12345, 123)
17922747853679707527695216231943419712992696443062340535140391466684
40953031931423861053031289352606613314821666096691426463815891552569
61299625923906846736377224598990446854741893321648522851663303862851
16587975372427272838604280411617304001701448802369380754772495091658
80584554994292720483269340987503673640044881128194397555564034430275
23561951313385041616743787240003466700321402142800004483416756392021
35945746171990585436418152506177298295938033884123488041067995268917
9117442108690738677978515625

In addition to the static methods offered by the BigInt class, you can do standard mathematical operations (addition, subtraction, multiplication, division) with big integers directly using the n numeric literal suffix:

PS > $num1 = 962822088399213984108510902933777372323n
PS > $num2 = 986516486816816168176871687167106806788n
PS > $num1 * $num2
949839864077222593647087206583370147511597229917261205272142276616785899728524

As an important note, when working with BigInt numbers be sure to always use the n numeric literal suffix (or enclose BigInt numbers in strings, and then cast them to the BigInt type). If you don’t, PowerShell thinks that you’re trying to provide a number of type Double (which loses data for extremely large numbers), and then converts that number to the big integer.

PS > $r = 962822088399213984108510902933777372323
PS > $r
9.62822088399214E+38

PS > [BigInt] $r
962822088399213912109618944997163270144

PS > [BigInt] 962822088399213984108510902933777372323
962822088399213912109618944997163270144

PS > [BigInt] "962822088399213984108510902933777372323"
962822088399213984108510902933777372323

Working with imaginary and complex numbers

When you need to work with calculations that involve the square root of −1, the System.Numerics.Complex class provides a great deal of support:

PS > [System.Numerics.Complex]::ImaginaryOne | Format-List

Real      : 0
Imaginary : 1
Magnitude : 1
Phase     : 1.5707963267949

In addition to the static methods offered by the Complex class, you can do standard mathematical operations (addition, subtraction, multiplication, division) with complex numbers directly:

PS > [System.Numerics.Complex]::ImaginaryOne *
    [System.Numerics.Complex]::ImaginaryOne | Format-List

Real      : -1
Imaginary : 0
Magnitude : 1
Phase     : 3.14159265358979

See Also

Recipe 3.12, “Learn About Types and Objects”