diff --git a/SignificantNumber.Test/SignificantNumberRangeTests.cs b/SignificantNumber.Test/SignificantNumberRangeTests.cs index f2864f9..423607b 100644 --- a/SignificantNumber.Test/SignificantNumberRangeTests.cs +++ b/SignificantNumber.Test/SignificantNumberRangeTests.cs @@ -56,6 +56,26 @@ public void Exp_ResultBelowDoubleRange_ReturnsNonzeroMagnitude() Assert.AreEqual(Parse("5.07595889755E-435"), result); } + [TestMethod] + [DataRow("2E308", "1")] + [DataRow("-1E400", "1")] + [DataRow("1E308", "1")] + [DataRow("-3E400", "1")] + public void Pow_NegativeOneToAnEvenIntegerBeyondDoubleRange_ReturnsOne(string power, string expected) => + Assert.AreEqual(Parse(expected), SignificantNumber.NegativeOne.Pow(Precise(power))); + + [TestMethod] + public void Pow_NegativeOneToAnOddIntegerBeyondDoubleRange_ReturnsNegativeOne() + { + PreciseNumber oddPower = Precise("2" + new string('0', 310) + "1"); + Assert.AreEqual(SignificantNumber.NegativeOne, SignificantNumber.NegativeOne.Pow(oddPower)); + Assert.AreEqual(SignificantNumber.NegativeOne, SignificantNumber.NegativeOne.Pow(PreciseNumber.Negate(oddPower))); + } + + [TestMethod] + public void Pow_NegativeOneToANonIntegerPower_StillThrowsArgumentException() => + Assert.ThrowsExactly(() => SignificantNumber.NegativeOne.Pow(Precise("0.5"))); + [TestMethod] public void Pow_PowerOfTenBeyondExponentRange_ThrowsOverflowException() { diff --git a/SignificantNumber/SignificantNumber.cs b/SignificantNumber/SignificantNumber.cs index f879e51..9179e20 100644 --- a/SignificantNumber/SignificantNumber.cs +++ b/SignificantNumber/SignificantNumber.cs @@ -605,6 +605,11 @@ public SignificantNumber Pow(PreciseNumber power) { return One; } + else if (Equal(this, NegativeOne) && PreciseNumber.IsInteger(power)) + { + // (-1)^n is exact for any integer n, however far beyond the range of a double it is. + return PreciseNumber.IsEvenInteger(power) ? One : NegativeOne; + } bool isNegativeBase = PreciseNumber.IsNegative(Value); if (isNegativeBase && !PreciseNumber.IsInteger(power))