Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ PublishScripts/
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# and except a Unity project's Packages/, which is source: Unity's package manifest and its
# resolved lock file are both meant to be committed, and a NuGet restore folder never contains
# a file by either name.
!**/[Pp]ackages/manifest.json
!**/[Pp]ackages/packages-lock.json
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
Expand Down Expand Up @@ -651,3 +656,16 @@ Temporary Items

# ImGui.ini files
imgui.ini

# Game engine projects
#
# Godot: the import cache, and the mono/temp bin+obj a C# build writes.
.godot/

# Unity: .meta files are source, not the Visual Studio C++ build artifact that the `*.meta` rule
# further up targets. Unity generates one per asset and it carries the GUID that scenes, prefabs
# and serialized references point at, so ignoring them gives every clone fresh GUIDs and silently
# breaks those references - including for a plug-in whose .dll is itself a build output. This
# negation has to come after that rule to win, and is scoped to the asset tree so the Visual
# Studio artifact stays ignored everywhere else.
!**/[Aa]ssets/**/*.meta
12 changes: 12 additions & 0 deletions SignificantNumber.Test/SignificantNumberPowExpPrecisionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,16 @@ public void Exp_PowerNearSevenHundred_ReportsTwelveSignificantDigits() =>
[TestMethod]
public void Pow_SmallLogarithmOfResult_KeepsTheDoublesPrecision() =>
Assert.AreEqual(15, Parse("1.2345678901234567890").Pow(Precise("0.5000000000000000001")).SignificantDigits);

// A base in the subnormal double range carries only a few digits as a double, so its logarithm must come
// from its significand and exponent. Reference values from Python decimal at 60 digits.
[TestMethod]
[DataRow("1.23456789e-320", "0.5000001", "1.11102926279157148966176568132872269505814553044809283401739E-160")]
[DataRow("1.23456789e-320", "-0.5000001", "9.00066302022865331618424814993882055897651460128454545426800E+159")]
public void Pow_SubnormalDoubleBase_ReportsOnlyCorrectDigits(string baseNumber, string power, string trueValue)
{
SignificantNumber result = Parse(baseNumber).Pow(Precise(power));
Assert.AreEqual(7, result.SignificantDigits);
AssertReportedDigitsAreCorrect(trueValue, result);
}
}
7 changes: 6 additions & 1 deletion SignificantNumber/SignificantNumber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@
/// <exception cref="DivideByZeroException">Thrown when the current number is zero and <paramref name="power"/> is negative.</exception>
/// <exception cref="ArgumentException">Thrown when the current number is negative and <paramref name="power"/> is not an integer, as the result is not a real number.</exception>
/// <exception cref="OverflowException">Thrown when the result's power of ten is too large or too small to represent.</exception>
public SignificantNumber Pow(PreciseNumber power)

Check warning on line 592 in SignificantNumber/SignificantNumber.cs

View workflow job for this annotation

GitHub Actions / ci / .NET / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 592 in SignificantNumber/SignificantNumber.cs

View workflow job for this annotation

GitHub Actions / ci / .NET / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 592 in SignificantNumber/SignificantNumber.cs

View workflow job for this annotation

GitHub Actions / ci / .NET / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 592 in SignificantNumber/SignificantNumber.cs

View workflow job for this annotation

GitHub Actions / ci / .NET / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.

Check warning on line 592 in SignificantNumber/SignificantNumber.cs

View workflow job for this annotation

GitHub Actions / ci / .NET / Analyze & Release

Refactor this method to reduce its Cognitive Complexity from 17 to the 15 allowed.
{
if (Equal(power, Zero))
{
Expand Down Expand Up @@ -652,7 +652,12 @@
// |x|^p = e^(p × ln|x|), so the digits are bounded by how precisely e^(p × ln|x|) is known.
significantDigits = CapToExponentPrecision(significantDigits, Log10OfMagnitude(value) * Math.Log(10) * power.To<double>());

double logValue = Math.Log(Math.Abs(value.To<double>()));
// A base outside the normal double range (subnormal, or beyond double.MaxValue) loses digits or becomes
// infinite as a double, so its logarithm is built from its significand and exponent instead.
double baseMagnitude = Math.Abs(value.To<double>());
double logValue = double.IsNormal(baseMagnitude)
? Math.Log(baseMagnitude)
: Log10OfMagnitude(value) * Math.Log(10);
double magnitude = Math.Exp(logValue * power.To<double>());
if (double.IsNormal(magnitude))
{
Expand Down Expand Up @@ -714,7 +719,7 @@
double magnitude = Math.Abs(exponent);
int lostDigits = !double.IsFinite(magnitude)
? DoubleSignificantDigits
: magnitude > 1 ? (int)Math.Ceiling(Math.Log10(magnitude)) : 0;

Check warning on line 722 in SignificantNumber/SignificantNumber.cs

View workflow job for this annotation

GitHub Actions / ci / .NET / Analyze & Release

Extract this nested ternary operation into an independent statement.

Check warning on line 722 in SignificantNumber/SignificantNumber.cs

View workflow job for this annotation

GitHub Actions / ci / .NET / Analyze & Release

Extract this nested ternary operation into an independent statement.

Check warning on line 722 in SignificantNumber/SignificantNumber.cs

View workflow job for this annotation

GitHub Actions / ci / .NET / Analyze & Release

Extract this nested ternary operation into an independent statement.

Check warning on line 722 in SignificantNumber/SignificantNumber.cs

View workflow job for this annotation

GitHub Actions / ci / .NET / Analyze & Release

Extract this nested ternary operation into an independent statement.

Check warning on line 722 in SignificantNumber/SignificantNumber.cs

View workflow job for this annotation

GitHub Actions / ci / .NET / Analyze & Release

Extract this nested ternary operation into an independent statement.

return int.Max(1, int.Min(significantDigits, DoubleSignificantDigits - lostDigits));
}
Expand Down
Loading