fix(display): Sig digit counting in formatGeneral, repeatable --with, doc nits#218
fix(display): Sig digit counting in formatGeneral, repeatable --with, doc nits#218
Conversation
…atable --with flag formatGeneral now counts significant digits (not characters) to match Excel's General format threshold. Also supports multiple --with flags on eval/evala commands and documents evala, --with syntax, --backend write-only behavior, and streaming CSV formula prefix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Code ReviewSummaryThis PR fixes a critical bug in formatGeneral where character count was used instead of significant digit count, causing incorrect scientific notation for values like -99999999.99. It also adds support for repeatable --with flags in the CLI and updates documentation. Strengths
Issues Found1. Bug in countSignificantDigits for zero values (Medium Priority)Line 146 has a logic error: else s.reverse.dropWhile(_ == '0').lengthThis returns 0 sig digits for input "0" when it should return 1. Suggested fix: else
val nonZero = s.reverse.dropWhile(_ == '0')
if nonZero.isEmpty then 1 else nonZero.length2. Missing unit tests (High Priority)countSignificantDigits is private with no direct test coverage. Add tests in DisplaySpec.scala for formatGeneral edge cases:
RecommendationsBefore merge:
Post-merge:
VerdictConditional Approve - pending zero-value fix The core logic is sound. Once the zero-value edge case is fixed and boundary tests are added, this is ready to merge. Great work on the detailed validation! |
Fix edge case where countSignificantDigits returned 0 for "0" input. Add 7 formatGeneral tests: zero, 9/10/11/12 sig digits, and scientific notation triggers for very small/large values. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Code ReviewSummaryThis PR makes three improvements: fixes the formatGeneral significant digit counting logic, adds repeatable --with flag support, and updates documentation. Overall, the changes are well-implemented with good test coverage. Strengths1. Core Bug Fix is CorrectThe formatGeneral fix properly addresses the root cause:
2. Excellent Test CoverageThe 7 new test cases in DisplaySpec.scala comprehensively cover:
3. Clean CLI RefactoringThe --with flag enhancement:
4. Documentation UpdatesSKILL.md additions document previously undocumented features and clarify edge cases. Minor Suggestions1. Consider Adding Boundary Test for 1e-4Test case to consider: values near the 1e-4 scientific notation threshold. At NumFmtFormatter.scala:137, scientific notation triggers when abs < 1e-4. Consider adding:
2. Note on doubleValue PrecisionAt NumFmtFormatter.scala:137, using rounded.doubleValue after careful BigDecimal rounding reintroduces floating-point precision issues. This is acceptable for matching Excel behavior, but worth noting as a known tradeoff. Security & Performance
Final VerdictLGTM with minor suggestions. The core bug fix is solid, test coverage is excellent, and the CLI enhancement is well-designed. Checklist
Recommendation: Merge after considering boundary test suggestion. Great work on the comprehensive test coverage! |
Test that 0.0001 (exactly at threshold) stays plain and that values below 1e-4 with >11 sig digits trigger scientific notation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
formatGeneralsignificant digits fix: Count significant digits (not characters) to match Excel's General format 11-digit threshold. Previously-99999999.99(10 sig digits) incorrectly triggered scientific notation because the string was 12 chars. Now rounds viaMathContext(11)instead of losing precision throughDouble.--withflag:eval/evalanow accept multiple--withflags (--with "A1=100" --with "B2=200") in addition to comma-separated syntax. UsesOpts.options(plural) with sharedparseOverrideshelper.evalacommand,--withcomma-separated syntax,--backendwrite-only behavior, streaming CSV formula prefix note.Test plan
./mill xl-core.test— 127 tests pass./mill xl-cli.test— 317 tests pass./mill __.checkFormat— clean./mill __.compile— clean--with "A=1,B=2"and--with "A=1" --with "B=2"produce identical resultsevala '=TRANSPOSE(B2:B5)'works🤖 Generated with Claude Code