Skip to content
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

Enhance helper.decimalPlaces #5992

Closed
wants to merge 2 commits into from
Closed

Conversation

costerwi
Copy link
Contributor

I think the new helper.decimalPlaces() function introduced in #5786 will be very helpful for generating ticks of fixed decimal places or scientific notation. Unfortunately, there were some tricky floating point issues which could fool it into returning too many decimals.

I've added some of those difficult cases to the tests and proposed an alternative calculation method which returns better results.

decimalPlaces now uses almostWhole to avoid floating point roundoff errors.
almostWhole required a small change to avoid issue when epsilon is so
small it doesn't change the sum.
Copy link
Contributor

@benmccann benmccann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the corresponding tests

@nagix
Copy link
Contributor

nagix commented Jan 19, 2019

Thanks for the contribution, but I feel it would be better to implement rounding function of floating point numbers separately. Currently, this helper method is only used for tick generation and it doesn’t require rounding. As described here, it is impossible to know the right precision only from the result, so I think it should be handled before calling decimalPlaces.

@costerwi
Copy link
Contributor Author

Thanks for the comments.

I'll use this function to calculate the digits in the tick spacing and then format all the ticks with that many digits using toFixed() or toExponential(). For that simple use It matters that the difference between 0.3 and 0.1 requires 1 digit, not 17.

Of course you are correct that 0.19999999999999998 has 17 digits but that’s not very useful. Unfortunately, rounding ahead of time doesn’t work reliably. For example, 3.1415e-34 has 38 digits, not 46 as currently returned.

As you probably know, the proposed function looks for a large gap in the digits. Such gaps are reasonably good indicators of the end of significant digits especially when working with "nice" values for tick spacing.

Copy link
Member

@kurkle kurkle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

almostWhole turns out better after the change.
New version of decimalPlaces however fails with some well presentable floating point numbers and that's not acceptable IMO.

@@ -126,7 +126,7 @@ module.exports = function() {
};
helpers.almostWhole = function(x, epsilon) {
var rounded = Math.round(x);
return (((rounded - epsilon) < x) && ((rounded + epsilon) > x));
return (((rounded - epsilon) <= x) && ((rounded + epsilon) >= x));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change seems reasonable.

e *= 10;
p++;
if (x > 0) {
while (x < 0.99 || !helpers.almostWhole(x, 1e-6)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This however fails with large numbers, for example (current version works with these):

		expect(helpers.decimalPlaces(12345678.1234)).toBe(4); // this PR results to 9
		expect(helpers.decimalPlaces(1234567890.1234567)).toBe(7); // this PR results to 6

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are good tests and I agree the result is not acceptable. I will review...

@benmccann
Copy link
Contributor

Hi @costerwi, are you still planning to pursue this PR? It's been inactive for awhile, so please let us know. Thanks!

@costerwi
Copy link
Contributor Author

costerwi commented Mar 2, 2019

Sorry, I've been distracted by other things lately. Probably won't get back to this for a while.

@benmccann
Copy link
Contributor

@costerwi would you like to just submit your changes to almostWhole to at least get those changes in then? Or if you'd like I can create a PR with those changes

@costerwi
Copy link
Contributor Author

costerwi commented Mar 8, 2019

Yes, please feel free to PR the improved almostWhole. Thanks!

@benmccann
Copy link
Contributor

Ok. Thanks for suggesting the fixes! I've sent a PR for the agreed upon parts in #6120

I'm going to close this PR just for the time being to keep the review queue clear and help us get through the outstanding PRs. When you feel like you have a fix you want us to review for helpers.decimalPlaces feel free to reopen this PR or create a new one with that change

Thanks again for this!

@benmccann benmccann closed this Mar 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants