-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add round
function
#53
Conversation
src/number/round.ts
Outdated
precision = | ||
precision == null | ||
? 0 | ||
: precision >= 0 | ||
? Math.min(precision, 307) | ||
: Math.max(precision, -323) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How can we verify these precision limits to be correct?
Interestingly, Lodash does this:
precision = precision == null
? 0
: (precision >= 0
? Math.min(precision, 292)
: Math.max(precision, -292))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aleclarson I added that check inspired from them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also i found an issue related with this: lodash/lodash#4232
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's what Claude Sonnet 3.5 says on the matter:
You're right to question this. Lodash's choice of 292 is indeed intentional and has a specific reason. Let me explain:
Precision: While JavaScript can theoretically represent numbers up to 308 decimal places, it doesn't maintain full precision for all of those digits.
Reliable accuracy: Lodash uses 292 as a more conservative limit to ensure reliable and consistent results across different JavaScript engines and environments.
IEEE 754 standard: This limit is related to the IEEE 754 double-precision floating-point format, which guarantees about 15-17 decimal digits of precision.
Safety margin: 292 provides a safety margin, avoiding potential rounding errors or inconsistencies that might occur when pushing to the absolute limits of JavaScript's number representation.
So, while 308 is technically the maximum exponent, Lodash's choice of 292 is a pragmatic one, prioritizing consistent and reliable results over the theoretical maximum. For most practical applications, this limit is more than sufficient and helps prevent subtle bugs that could arise from pushing the boundaries of floating-point precision.
I will push an update, along with the Lodash test suite and a reimplementation to support the edge cases that lodash.round
does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @aleclarson for the explanation. So they chose 292 to ensure results are reliable and consistent across different JavaScript engines (e.g., V8 in Chrome, SpiderMonkey in Firefox) and environments (e.g., browsers, Node.js).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tracked down the original commit:
lodash/lodash@68ae6fc
Not much justification is given. If we can use technically “more correct” limits, we should as long as NaN
is avoided. If someone reports misbehavior in some JS engine, we'll consider a breaking change then, but considering such large precision values are probably very rare in Javascript code, that won't happen anytime soon. Besides, the caller can always wrap/fork Radashi round
to clamp the precision to 292 if necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So to be on the safe side shall we stick with 292 then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some testing, I found that 292
is the upper limit that prevents NaN in all cases, while -323
works fine as a lower limit in all cases.
Thanks for the contribution! Hope to see more from you in the future. |
Tip
The owner of this PR can publish a preview release by commenting
/publish
in this PR. Afterwards, anyone can try it out by runningpnpm add radashi@pr<PR_NUMBER>
.Summary
The round function is designed to round a given number to a specified precision.
Related issue, if any:
sodiray/radash#61
What kind of change does this PR introduce?
Feature
For any code change,
Does this PR introduce a breaking change?
No