mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-22 05:48:37 +00:00
Fixed Pow function to handle edge cases and wrote tests to check that they are handled correctly.
This commit is contained in:
parent
fe9b4c7e1d
commit
c2b83a6779
2 changed files with 128 additions and 1 deletions
|
|
@ -46,6 +46,27 @@ namespace Cosmos.Compiler.Tests.Bcl.System
|
|||
result = Math.Exp(1.5);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 4.48168907033806), "e^1.5 returns correct result");
|
||||
|
||||
result = Math.Exp(0);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 1), "e^0 gives correct result");
|
||||
|
||||
result = Math.Exp(1);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, Math.E), "e^1 gives correct result");
|
||||
|
||||
result = Math.Exp(double.PositiveInfinity);
|
||||
Assert.IsTrue(result == double.PositiveInfinity, "e^Infinity gives correct result");
|
||||
|
||||
result = Math.Exp(double.NegativeInfinity);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 0), "e^-Infinity gives correct result");
|
||||
|
||||
result = Math.Exp(double.NaN);
|
||||
Assert.IsTrue(double.IsNaN(result), "e^NaN gives correct result");
|
||||
|
||||
result = Math.Exp(double.MaxValue);
|
||||
Assert.IsTrue(double.IsPositiveInfinity(result), "e^0 gives correct result");
|
||||
|
||||
result = Math.Exp(double.MinValue);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 0), "e^0 gives correct result");
|
||||
|
||||
#endregion Math.Exp
|
||||
|
||||
#region Math.Pow
|
||||
|
|
@ -69,6 +90,70 @@ namespace Cosmos.Compiler.Tests.Bcl.System
|
|||
result = Math.Pow(2, -1);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 0.5), "Pow gives correct results when handling negative powers");
|
||||
|
||||
//Have double as base
|
||||
result = Math.Pow(0.5, 2);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 0.25), "Pow gives correct solution with double base");
|
||||
|
||||
//x = Nan
|
||||
result = Math.Pow(double.NaN, 2);
|
||||
Assert.IsTrue(double.IsNaN(result), "Pow gives correct solution when x is NaN");
|
||||
//Y = Nan
|
||||
result = Math.Pow(10, double.NaN);
|
||||
Assert.IsTrue(double.IsNaN(result), "Pow gives correct solution when y is NaN");
|
||||
//y = 0
|
||||
result = Math.Pow(10, 0);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 1), "Pow gives correct solution when y is 0");
|
||||
//x = -Inf y < 0 == 0
|
||||
result = Math.Pow(double.NegativeInfinity, -2);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 0), "Pow gives correct solution when X is -INF and y is negative");
|
||||
//x = -Inf y > 0 && y is even == Inf
|
||||
result = Math.Pow(double.NegativeInfinity, 2);
|
||||
Assert.IsTrue(double.IsPositiveInfinity(result), "Pow gives correct solution when x is -INF and y is even");
|
||||
//x is -INF and y is positive odd == -INF
|
||||
result = Math.Pow(double.NegativeInfinity, 3);
|
||||
Assert.IsTrue(double.IsNegativeInfinity(result), "Pow gives correct solution when x is -INF and y is odd");
|
||||
//x < 0 && y is not integer or special case
|
||||
result = Math.Pow(-3, 0.25);
|
||||
Assert.IsTrue(double.IsNaN(result), "Pow gives correct solution when x is negative and y is non integer");
|
||||
//x = -1 && y is Inf == Nan
|
||||
result = Math.Pow(-1, double.PositiveInfinity);
|
||||
Assert.IsTrue(double.IsNaN(result), "Pow gives correct solution when x is -1 and y is INF");
|
||||
//x = -1 && y is -Inf == Nan
|
||||
result = Math.Pow(-1, double.NegativeInfinity);
|
||||
Assert.IsTrue(double.IsNaN(result), "Pow gives correct solution when x is -1 and y is -INF");
|
||||
//-1 < x < 1 + y = -Inf
|
||||
result = Math.Pow(-0.25, double.NegativeInfinity);
|
||||
Assert.IsTrue(double.IsPositiveInfinity(result), "Pow gives correct solution when -1 < x < 0 and y = -INF");
|
||||
result = Math.Pow(0.25, double.NegativeInfinity);
|
||||
Assert.IsTrue(double.IsPositiveInfinity(result), "Pow gives correct solution when 0 < x < 1 and y = -INF");
|
||||
//-1 < x < 1 + y = Inf
|
||||
result = Math.Pow(-0.25, double.PositiveInfinity);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 0), "Pow gives correct solution when -1 < x < 0 and y is INF");
|
||||
result = Math.Pow(0.25, double.PositiveInfinity);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 0), "Pow gives correct solution when 0 < x < 1 and y is INF");
|
||||
//-1 > x || x > 1 + y = -Inf
|
||||
result = Math.Pow(-1.5, double.NegativeInfinity);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 0), "Pow gives correct solution when x < -1 and y is -INF");
|
||||
result = Math.Pow(1.5, double.NegativeInfinity);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 0), "Pow gives correct solution when x > 1 and y is -INF");
|
||||
//-1 > x || x > 1 + y = Inf
|
||||
result = Math.Pow(-1.25, double.PositiveInfinity);
|
||||
Assert.IsTrue(double.IsPositiveInfinity(result), "Pow gives correct solution when -1 > x and y = INF");
|
||||
result = Math.Pow(1.25, double.PositiveInfinity);
|
||||
Assert.IsTrue(double.IsPositiveInfinity(result), "Pow gives correct solution when x > 1 and y = INF");
|
||||
//x = 0 y > 0
|
||||
result = Math.Pow(0, 2);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 0), "Pow gives correct solution when x = 0 any y > 0 ");
|
||||
//x = 0 y < 0
|
||||
result = Math.Pow(0, -3);
|
||||
Assert.IsTrue(double.IsPositiveInfinity(result), "Pow gives correct solution when x is 0 and y < 0 ");
|
||||
//x = inf y < 0
|
||||
result = Math.Pow(double.PositiveInfinity, -5);
|
||||
Assert.IsTrue(EqualityHelper.DoublesAreEqual(result, 0), "Pow gives correct solution when x is INF and y < 0 ");
|
||||
//x = inf y > 0
|
||||
result = Math.Pow(double.PositiveInfinity, 5);
|
||||
Assert.IsTrue(double.IsPositiveInfinity(result), "Pow gives correct solution when x is INF and y > 0 ");
|
||||
|
||||
#endregion Math.Pow
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -440,9 +440,51 @@ namespace Cosmos.System_Plugs.System
|
|||
{
|
||||
if (e == 0) return 1;
|
||||
if (e == 1) return b;
|
||||
if (double.IsNaN(b) || double.IsNaN(e)) return double.NaN;
|
||||
if (double.IsNegativeInfinity(b))
|
||||
{
|
||||
if (e < 0)
|
||||
return 0;
|
||||
if ((long)e % 2 == 0)
|
||||
return double.PositiveInfinity;
|
||||
else
|
||||
return double.NegativeInfinity;
|
||||
}
|
||||
if (double.IsPositiveInfinity(b))
|
||||
{
|
||||
if (e < 0)
|
||||
return 0;
|
||||
else
|
||||
return double.PositiveInfinity;
|
||||
}
|
||||
if (double.IsInfinity(e))
|
||||
{
|
||||
bool t = -1 < b;
|
||||
bool t1 = 1 > b;
|
||||
if (t && t1)
|
||||
|
||||
if (double.IsPositiveInfinity(e))
|
||||
return 0;
|
||||
else
|
||||
return double.PositiveInfinity;
|
||||
else
|
||||
{
|
||||
bool v = b < -1;
|
||||
bool v1 = 1 < b;
|
||||
if (v || v1)
|
||||
{
|
||||
if (double.IsPositiveInfinity(e))
|
||||
return double.PositiveInfinity;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return double.NaN;
|
||||
}
|
||||
}
|
||||
if (b < 0)
|
||||
{
|
||||
if (Math.Abs(e % 1) <= (Double.Epsilon * 100)) throw new ArgumentException("This will produce non-real answer");
|
||||
if (Math.Abs(e) - Math.Abs((int)e) > (Double.Epsilon * 100)) return double.NaN;
|
||||
double logedBase = Math.Log(Math.Abs(b));
|
||||
double pow = Exp(logedBase * e);
|
||||
if ((long)e % 2 == 0) return pow;
|
||||
|
|
|
|||
Loading…
Reference in a new issue