fix: use BigInt for large integers to preserve precision#28
fix: use BigInt for large integers to preserve precision#28remorses wants to merge 4 commits intolukeed:masterfrom
Conversation
Numbers larger than Number.MAX_SAFE_INTEGER lose precision when converted to JavaScript Number. This change detects integer strings that would lose precision and returns BigInt instead. - 9007199254740991 (MAX_SAFE_INTEGER) -> Number - 9007199254740993 -> BigInt (would lose precision as Number) - 1e7, 3.14, etc -> Number (floats unchanged)
There was a problem hiding this comment.
Pull request overview
This PR fixes precision loss for large integers in command-line argument parsing by automatically using BigInt for integer strings that exceed JavaScript's safe integer range (2^53-1). The implementation adds a new toNum function that detects when numeric conversion would lose precision and uses BigInt instead.
Changes:
- Added
toNumfunction to detect and preserve precision for large integers using BigInt - Refactored numeric conversion logic in
toValto use the newtoNumfunction - Added comprehensive tests for BigInt boundary conditions and negative large integers
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/index.js | Implements new toNum function with BigInt support for precision-loss detection and integrates it into the value conversion logic |
| test/num.js | Adds three test cases covering large integer BigInt conversion, MAX_SAFE_INTEGER boundary behavior, and large negative integers |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Fix leading zeros incorrectly becoming BigInt - Add MIN_SAFE_INTEGER boundary test - Add leading zeros test
|
This is technically a breaking change, as bigints werent supported in Node until 10.x and this lib is still 4+ While this PR is technically correct, I wonder how frequent it's being bumped into Thoughts? |
|
I can update the PR to return a number if BigInt constructor is missing. I don't think making a breaking change for this issue is worth it. Number parsing is a fine in my opinion |
- Check typeof BigInt !== 'undefined' before using BigInt() - Move BigInt tests to _bigint.js (not matched by tape glob) - Conditionally require BigInt tests when available
Fixes #29
Numbers larger than
Number.MAX_SAFE_INTEGER(2^53-1) lose precision when converted to JavaScript Number.This affects downstream packages like cac which uses mri for argument parsing.
Behavior:
numberbigintnumber(unchanged)Tests added:
cc @lukeed