1
0
mirror of https://github.com/oliverbooth/X10D synced 2024-11-26 12:18:48 +00:00

Rework Sqrt methods

Implemented using a method invented by Isaac Newton, authored by SLenik on StackOverflow CC-BY-SA 3.0 https://stackoverflow.com/a/6755197/1467293
This commit is contained in:
Oliver Booth 2022-04-21 12:21:38 +01:00
parent 9b9b75ae5b
commit e7e8d75fba
No known key found for this signature in database
GPG Key ID: 32A00B35503AF634
2 changed files with 52 additions and 2 deletions

View File

@ -208,10 +208,35 @@ public static class DoubleExtensions
/// <see cref="ComplexSqrt" />. /// <see cref="ComplexSqrt" />.
/// </remarks> /// </remarks>
/// <seealso cref="ComplexSqrt" /> /// <seealso cref="ComplexSqrt" />
/// <author>SLenik https://stackoverflow.com/a/6755197/1467293</author>
/// <license>CC BY-SA 3.0</license>
[Pure] [Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static double Sqrt(this double value) public static double Sqrt(this double value)
{ {
return Math.Sqrt(value); switch (value)
{
case 0:
return 0;
case < 0 or double.NaN:
return double.NaN;
case double.PositiveInfinity:
return double.PositiveInfinity;
}
double previous;
double current = Math.Sqrt(value);
do
{
previous = current;
if (previous == 0.0)
{
return 0;
}
current = (previous + value / previous) / 2;
} while (Math.Abs(previous - current) > double.Epsilon);
return current;
} }
} }

View File

@ -207,10 +207,35 @@ public static class SingleExtensions
/// <see cref="ComplexSqrt" />. /// <see cref="ComplexSqrt" />.
/// </remarks> /// </remarks>
/// <seealso cref="ComplexSqrt" /> /// <seealso cref="ComplexSqrt" />
/// <author>SLenik https://stackoverflow.com/a/6755197/1467293</author>
/// <license>CC BY-SA 3.0</license>
[Pure] [Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static float Sqrt(this float value) public static float Sqrt(this float value)
{ {
return MathF.Sqrt(value); switch (value)
{
case 0:
return 0;
case < 0 or float.NaN:
return float.NaN;
case float.PositiveInfinity:
return float.PositiveInfinity;
}
float previous;
float current = MathF.Sqrt(value);
do
{
previous = current;
if (previous == 0.0f)
{
return 0;
}
current = (previous + value / previous) / 2;
} while (MathF.Abs(previous - current) > float.Epsilon);
return current;
} }
} }