PowerShell Script/Cmdlet: Get-NthRoot

A PowerShell function that computes the principal nth root n^A of positive real number A.
Installation Instructions:
- Determine where your local scripts directory is with the following command:
([IO.DirectoryInfo](Join-Path $Profile.CurrentUserCurrentHost ".." "Scripts")).FullName - Create a new file within that directory and name it
Get-NthRoot.ps1. - 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
Post a Comment