-
Notifications
You must be signed in to change notification settings - Fork 274
fix: Avoid floating point errors when rounding in string() #271
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
base: master
Are you sure you want to change the base?
Conversation
Hmm. I'm not sure I like this. Could we instead make That would satisfy all the usecases without being incredibly broken. I can't imagine a usecase where "round too precision and then perform some more math on it" makes any amount of sense, but the "round to fixed precision as a string" definitely does. It'd still be a breaking change but at least more amicable for people to migrate to this less broken behavior. |
It happens indirectly through normal colour manipulation. Take the rgb implementation in your library: you round because, well, rgb colours don't need to be kept at high precision. But then if you lighten or darken that colour a number of times (e.g. you generate a palette from a single rgb), those computations will be done on a less-accurate value and will accumulate accuracy errors every time they're rounded (i.e. every time a rgb is created from another rgb). To make sure I understand you well, you'd like me to:
|
Right, I agree. I was referring more to the fact that I can't imagine a case where that's useful outside of
That'd satisfy most of the usecases, I think. tl;dr any op that results in a string (e.g. Then no more accumulated errors. |
BREAKING CHANGE: This commit removes the precision argument from round(), making it return integers. It introduces a toFixed() function as a proxy replacement.
@Qix- I've reworked the commit so that now, |
Co-authored-by: Josh Junon <Qix-@users.noreply.github.com>
Hi @Qix-, do you know when you'll have time to review this PR again? I'd love to get rid of the hotfix I maintain on my end as a consumer of the library :) |
return new Color([...this.color.map(roundToPlace(places)), this.valpha], this.model); | ||
round() { | ||
if ((arguments?.length ?? 0) !== 0) { | ||
console.warn('Color.round() no longer accepts a precision argument and now rounds to the nearest integer. Consider using Color.toFixed() if you want to retrieve color elements with a precision argument.'); |
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.
Don't log anything to users since this is a CLI widely used package. Your log may break some apps.
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 agree with you, but I need some sort of safeguard here.
Calling with an unused argument (the old way) will not cause any error per se but will cause the library to return colours that are rounded differently. It's a silent data corruption that users would need to spend time finding the root cause of.
There is a breaking change notice describing this API change, but of course many people upgrade breaking versions without reading changelogs. I could explicitly throw, which would at least more predictably solve the underlying issue I want to solve. But doing and logging nothing would likely be detrimental here.
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.
This can be released as a new major since it is breaking. Let's just throw new TypeError('.round() takes no arguments')
here.
Also you can just do if (arguments?.length)
looking at this again.
BREAKING CHANGE: This commit removes the precision argument from round(), making it return integers. It introduces a toFixed() function as a proxy replacement.
Closes #127.