Skip to content

Commit 84dd26a

Browse files
committed
Count trailing zeros in IsEvenInteger and IsOddInteger
Trailing zeros are stored in the exponent, so 10 is significand 1 at exponent 1. The parity checks read only the significand, so every multiple of 10 whose significand was odd (10, 30, 100, ...) reported as odd. Any positive exponent makes the value a multiple of 10 and therefore even; only a value at exponent 0 takes its parity from the significand. Fixes #104 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AEYBNCRr6chFLiZDv1MVj
1 parent 299fd76 commit 84dd26a

2 files changed

Lines changed: 48 additions & 2 deletions

File tree

‎PreciseNumber.Test/PreciseNumberTests.cs‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,42 @@ public void TestIsOddInteger()
543543
Assert.IsFalse(PreciseNumber.IsOddInteger(two), "Two should not be an odd integer");
544544
}
545545

546+
// Trailing zeros are stored in the exponent, so 10 is significand 1 at exponent 1. The parity
547+
// checks used to read only the significand, which made every multiple of 10 look odd.
548+
549+
[TestMethod]
550+
[DataRow(10)]
551+
[DataRow(100)]
552+
[DataRow(30)]
553+
[DataRow(-20)]
554+
[DataRow(1000000)]
555+
public void TestIsEvenIntegerForMultiplesOfTen(int value)
556+
{
557+
PreciseNumber number = value.ToPreciseNumber();
558+
Assert.IsTrue(PreciseNumber.IsEvenInteger(number), $"{value} should be an even integer");
559+
Assert.IsFalse(PreciseNumber.IsOddInteger(number), $"{value} should not be an odd integer");
560+
}
561+
562+
[TestMethod]
563+
public void TestParityOfASumWithTrailingZero()
564+
{
565+
PreciseNumber sum = 7.ToPreciseNumber() + 3.ToPreciseNumber();
566+
Assert.IsTrue(PreciseNumber.IsEvenInteger(sum), "7 + 3 should be an even integer");
567+
Assert.IsFalse(PreciseNumber.IsOddInteger(sum), "7 + 3 should not be an odd integer");
568+
}
569+
570+
[TestMethod]
571+
[DataRow(1)]
572+
[DataRow(-3)]
573+
[DataRow(21)]
574+
[DataRow(1001)]
575+
public void TestIsOddIntegerForOddValues(int value)
576+
{
577+
PreciseNumber number = value.ToPreciseNumber();
578+
Assert.IsTrue(PreciseNumber.IsOddInteger(number), $"{value} should be an odd integer");
579+
Assert.IsFalse(PreciseNumber.IsEvenInteger(number), $"{value} should not be an even integer");
580+
}
581+
546582
[TestMethod]
547583
public void TestIsPositive()
548584
{

‎PreciseNumber/PreciseNumber.cs‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,7 +1045,13 @@ public static PreciseNumber Abs(PreciseNumber value) =>
10451045
public static bool IsComplexNumber(PreciseNumber value) => !IsRealNumber(value);
10461046

10471047
/// <inheritdoc/>
1048-
public static bool IsEvenInteger(PreciseNumber value) => IsInteger(value) && value.Significand.IsEven;
1048+
/// <remarks>
1049+
/// Trailing zeros are stored in <see cref="Exponent"/>, so 10 is significand 1 at exponent 1. The
1050+
/// significand's parity is the value's only at exponent 0; any positive exponent makes the value a
1051+
/// multiple of 10, and so even.
1052+
/// </remarks>
1053+
public static bool IsEvenInteger(PreciseNumber value) =>
1054+
IsInteger(value) && (value.Exponent > 0 || value.Significand.IsEven);
10491055

10501056
/// <inheritdoc/>
10511057
public static bool IsFinite(PreciseNumber value) => true;
@@ -1077,7 +1083,11 @@ public static bool IsInteger(PreciseNumber value) =>
10771083
public static bool IsNormal(PreciseNumber value) => true;
10781084

10791085
/// <inheritdoc/>
1080-
public static bool IsOddInteger(PreciseNumber value) => IsInteger(value) && !value.Significand.IsEven;
1086+
/// <remarks>
1087+
/// Only a value at exponent 0 can be odd, for the reason given on <see cref="IsEvenInteger"/>.
1088+
/// </remarks>
1089+
public static bool IsOddInteger(PreciseNumber value) =>
1090+
IsInteger(value) && value.Exponent == 0 && !value.Significand.IsEven;
10811091

10821092
/// <inheritdoc/>
10831093
public static bool IsPositive(PreciseNumber value) =>

0 commit comments

Comments
 (0)