Skip to content

Stop multiplying by zero from throwing when the zero is on the right [patch] - #110

Merged
matt-edmondson merged 2 commits into
mainfrom
fix/multiply-by-zero-throws
Sep 28, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
fix/multiply-by-zero-throws

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #108

What was wrong

LowestSignificantDigits, used by Multiply, Divide, Mod and CompareTo, read the left count after it had already overwritten it. When both operands were -1, 0 or 1, the result depended on operand order. A zero on the right gave a count of 0, and ToSignificantNumber(0) throws. So 1 * 0, 0 * 0 and default * default threw, while 0 * 1 returned 0.

Fix

  • Capture both unlimited-precision flags before choosing a count.
  • When both operands are exact, return 1. Any product, quotient or remainder of -1, 0 and 1 is exact at one significant digit.
  • Otherwise, behaviour is unchanged: an exact operand defers to the other one's count, and two inexact operands take the lower count.

The same change makes CompareTo antisymmetric for these values. Before, 1.CompareTo(0) returned 0 while 0.CompareTo(1) returned -1.

Tests

The new SignificantNumberExactOperandTests covers:

  • the repro lines from the issue
  • Square(SignificantNumber.Zero) through generic math
  • a * b == b * a == exact for every pair drawn from {-1, 0, 1}
  • exact Divide/Mod results
  • CompareTo sign for every pair

With the fix reverted, 7 of these fail. With it, all 120 tests pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QBrEwaLGeo2SvjVK3AnLrp


Generated by Claude Code

…[patch]

LowestSignificantDigits read the left count after overwriting it, so when both
operands were -1, 0 or 1 the result depended on operand order and a zero on the
right produced a count of 0, which ToSignificantNumber rejects. Capture both
unlimited-precision flags first, and return 1 when both operands are exact,
since any product, quotient or remainder of -1, 0 and 1 is exact at one digit.

This also makes CompareTo antisymmetric for those values (1.CompareTo(0) was 0).

Fixes #108

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QBrEwaLGeo2SvjVK3AnLrp
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 36e7f12 into main Sep 28, 2026
12 checks passed
@matt-edmondson
matt-edmondson deleted the fix/multiply-by-zero-throws branch September 28, 2026 01:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 * 0, 0 * 0 and default * default throw ArgumentOutOfRangeException ("Significant digits must be greater than zero"), while 0 * 1 returns 0

2 participants