Skip to content

Feat/dual int64 18 18 precision#31

Draft
PKartaviy wants to merge 12 commits intorobaho:masterfrom
PKartaviy:feat/dual-int64-18-18-precision
Draft

Feat/dual int64 18 18 precision#31
PKartaviy wants to merge 12 commits intorobaho:masterfrom
PKartaviy:feat/dual-int64-18-18-precision

Conversation

@PKartaviy
Copy link
Copy Markdown

@PKartaviy PKartaviy commented Jan 26, 2026

Summary

Redesigns the fixed-point library from single int64 (10.8 digits) to dual int64 (18.18 digits) to support extended range and precision.

Changes

  • Data Structure: Changed from single fp int64 to hi int64, lo int64 (16 bytes total)
  • Range: ±999,999,999,999,999,999 (18 integer digits)
  • Precision: 18 decimal places
  • Operations: All arithmetic, comparison, rounding, and conversion functions updated
  • Serialization: Binary format changed (breaking change for v2.0)

Performance

  • Addition: 2.4 ns/op, 0 allocations
  • Multiplication: 163.7 ns/op, 5 allocations (using math/big)
  • Division: 350.1 ns/op, 10 allocations (using math/big)
  • Comparison: 1.88 ns/op, 0 allocations

Test Results

✅ All 29 tests passing
✅ Extended precision validated: 123456789012345678.123456789012345678
✅ Division accuracy: 2/3 = 0.666666666666666667 (18 digits)
✅ Serialization round-trip working correctly

Breaking Changes

  • Binary serialization format has changed (clean break, v2.0)
  • No migration support needed as per design decisions

🤖 Generated with Claude Code

PKartaviy and others added 4 commits January 25, 2026 19:00
Redesigns the fixed-point library from single int64 (10.8 digits) to dual
int64 (18.18 digits) to support 18 integer digits and 18 decimal places.
This provides extended range (±999 quadrillion) and precision while
maintaining acceptable performance using math/big for multiplication and
division operations.

Major changes:
- Changed struct from single fp field to hi/lo fields (16 bytes total)
- Updated all arithmetic operations with sign-consistent normalization
- Implemented arbitrary precision Mul/Div using math/big
- Extended precision from 8 to 18 decimal places
- Updated all tests to reflect new precision expectations
- Binary serialization format changed (v2.0 breaking change)

Performance characteristics:
- Addition: 2.4 ns/op, 0 allocations
- Multiplication: 163.7 ns/op, 5 allocations
- Division: 350.1 ns/op, 10 allocations
- Comparison: 1.88 ns/op, 0 allocations

All tests passing with extended range validation.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@PKartaviy PKartaviy marked this pull request as draft January 26, 2026 05:50
@robaho
Copy link
Copy Markdown
Owner

robaho commented Feb 5, 2026

I don’t think this PR is necessary. You might as well just use bignum which uses variable size storage

PKartaviy and others added 8 commits February 15, 2026 21:52
Fixes five critical bugs discovered during thorough testing:

1. Overflow detection in Add/Sub operations
   - Add and Sub now properly return NaN when result exceeds ±999,999,999,999,999,999
   - Prevents invalid values beyond 18-digit range

2. Overflow detection in Mul operation
   - Multiplication now checks result against maxHi after normalization
   - Ensures consistency between Add and Mul for large values

3. Input validation overflow check
   - Changed from imprecise float comparison to direct integer check
   - NewS and NewI now use maxHi constant for accurate validation

4. Division rounding error with negative numbers
   - Fixed -1/3 returning -0.333333333333333335 instead of -0.333333333333333333
   - Changed from DivMod (Euclidean) to QuoRem (truncated division)
   - Fixed lo calculation to use subtraction instead of Mod for sign consistency

5. String parsing for "-.5" format
   - Added handling for sign prefix before decimal point with no integer part
   - Parsing "-.5", "+.5" now works correctly

Added comprehensive_test.go with 20+ edge case tests covering:
- Sign consistency across operations
- Overflow and underflow conditions
- Rounding edge cases (floor, ceil, round)
- Negative zero handling
- Operation properties (commutativity, associativity, identity)
- Binary serialization round-trips
- Float conversion precision limits
- String parsing edge cases

All 50+ tests passing. Division performance improved from 350ns to 294ns per op.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replace the math/big-based Mul (~160ns, 5 allocs) with a pure int64
schoolbook multiplication in base 10^9 (~10ns, 0 allocs), achieving
~16x speedup. The old implementation is preserved as MulSlow for
reference and testing. Includes TestMulVsMulSlow with 17 table-driven
cases and 10k random iterations confirming exact equivalence.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Early-return ZERO when either operand is zero, instead of letting
a wrong `negative` flag propagate through the function. Fix stale
comment that referenced incorrect digit indices. Expand test suite
with zero*negative cases, large hi values (a[0]>0 in base-10^9),
overflow cases, and a second random loop covering hi up to maxHi.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace string-based float64 conversion with strconv.AppendFloat into a
[64]byte stack buffer and manual byte parsing, eliminating all heap
allocations. Rename the old implementation to NewFSlow for comparison.

~2.2x faster (50ns vs 111ns), 0 allocs (down from 1 alloc/24 bytes).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…gorithm D)

Replaces math/big-based division with stack-only int64 arithmetic,
achieving ~4x speedup (64 ns/op vs 258 ns/op) and zero allocations.
Old implementation preserved as DivSlow for reference and testing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace fmt.Sprintf + strconv.FormatInt + string concatenation with
right-to-left digit writing into a [40]byte stack buffer. Reduces
String/StringN/MarshalJSON from 4 allocs (80 B) to 1 alloc (32 B)
and improves throughput ~3x.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
160 test cases covering String(), StringN(), MarshalJSON() across
edge cases: zero-padded fractions, min/max values, round-trips,
arithmetic results, point position, output length bounds, and
JSON marshal/unmarshal consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

2 participants