PowerShell Script/Cmdlet: Get-NthRoot

A PowerShell function that computes the principal nth root n^A of positive real number A.


Installation Instructions:

  1. Determine where your local scripts directory is with the following command: ([IO.DirectoryInfo](Join-Path $Profile.CurrentUserCurrentHost ".." "Scripts")).FullName
  2. Create a new file within that directory and name it Get-NthRoot.ps1.
  3. Copy and paste the contents below into that file and save it.
function Get-NthRoot { <# .SYNOPSIS Computes the principal nth root n^A of positive real number A. .DESCRIPTION The `Get-NthRoot` cmdlet computes the principal nth root n^A of positive real number A. .PARAMETER Radicand Specifies the radicand, or A. .PARAMETER Degree Specifies the degree, or n. .PARAMETER Precision Specifies the number of significant figures (decimal places) to compute. .INPUTS None You cannot pipe objects to Get-NthRoot. .OUTPUTS System.Decimal Get-NthRoot returns a decimal number. .NOTES Results from Get-NthRoot are subject to varying amounts of degradation in accuracy when run through any other function, commandlet, assembly method, et cetera that offers less precision than the System.Decimal type, which this function uses. Consider casting values from subsequent operations that use Get-NthRoot's own result(s) as System.Decimal as well, unless the aforementioned values are inherently degraded in accuracy (e.g. if they were calculated using a method provided by System.Math, which can only output results in the less-accurate System.Double type). The `Precision` parameter is limited to a maximum value of 32 to try and prevent situations e.g. where a floating point "value" of PositiveInfinity or NegativeInfinity becomes the only attainable result, the function is terminated by the PowerShell host for memory usage reasons, and similar. This function requires PowerShell version 7.3.0 or greater. .EXAMPLE ((Get-NthRoot -Radicand 5 -Degree 2 -Precision 15) + 1) / 2 1.618033988749895 Computes the golden ratio to fifteen significant figures. .EXAMPLE [Decimal] $Global:Phi = ((Get-NthRoot 5 2) + 1) / 2 PS > $Phi 1.6180339887498948482045868384 Creates the variable $Phi within the Global scope for convenient access to the golden ratio whenever and wherever desired. .EXAMPLE $semitone = Get-NthRoot -Radicand 2 -Degree 12 -Precision 5 PS > $noteFreq = @{ 'C' = 16.35160; 'C#' = 17.32391; 'D' = 18.35405 >> 'D#' = 19.44544; 'E' = 20.60172; 'F' = 21.82676 >> 'F#' = 23.12465; 'G' = 24.49971; 'G#' = 25.95654 >> 'A' = 27.50000; 'A#' = 29.13524; 'B' = 30.86771 } PS > "$([Math]::Round($noteFreq['C'] * [Math]::Pow($semitone, 12 * 5), 2)) Hz" 523.25 Hz Uses the twelfth root of two to five significant figures to compute the frequency, in hertz, of the fifth octave of musical note C. The table of fundamental frequencies defined by $noteFreq are in the zeroth SPN† octave. †: Scientific pitch notation .LINK about_Arithmetic_Operators #> # Yes, casting nearly every value in this function as System.Decimal really # is necessary to prepare for trouble and not make it System.Double (team # dotnet, blasting off at slightly slower than the speed of light because it # really hates big numbers). [CmdletBinding(PositionalBinding = $true, SupportsPaging = $false, SupportsShouldProcess = $false)] [OutputType([Decimal])] param( [Parameter(Mandatory = $true, Position = 0)] [ValidateNotNullOrEmpty()] [Decimal] $Radicand, [Parameter(Mandatory = $true, Position = 1)] [ValidateNotNullOrEmpty()] [Decimal] $Degree, [Parameter(Mandatory = $false, Position = 2)] [ValidateRange(1, 32)] [Int16] $Precision = 10 ) begin { #Requires -Version 7.3 Set-StrictMode -Version 3.0 [Decimal] $Script:Epsilon = '1E-' + $Precision function Script:Power { [OutputType([Decimal])] param( [Parameter(Mandatory = $true, Position = 0)] [ValidateNotNullOrEmpty()] [Decimal] $Base, [Parameter(Mandatory = $true, Position = 1)] [ValidateNotNullOrEmpty()] [Decimal] $Exponent ) begin { [Decimal] $Result = 1 } process { for ($i = 1; $i -le $Exponent; $i++) { $Result *= $Base } } end { return $Result } clean { Remove-Variable -Name 'Result' } } } process { # Ensure that n is positive without making use of the Abs method offered by System.Math, for # obvious reasons. if (0 + $Degree -lt 0) { [Decimal] $AbsDeg =- $Degree } else { [Decimal] $AbsDeg = $Degree } [Decimal] $Result = 1 # Individually calculate each decimal place requested and append it to the return value. do { [Decimal] $SigFig = ($Radicand / (Script:Power $Result ($AbsDeg - 1)) - $Result) / $AbsDeg $Result += $SigFig } while ($SigFig -lt -$Script:Epsilon -or $SigFig -gt $Script:Epsilon) } end { if (0 + $Degree -lt 0) { return 1 / $Result } else { return $Result } } }

Magic Spearmint

Comments