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

Rounding errors with Color.hsl().string() #127

Open
s2tephen opened this issue Sep 26, 2017 · 15 comments
Open

Rounding errors with Color.hsl().string() #127

s2tephen opened this issue Sep 26, 2017 · 15 comments

Comments

@s2tephen
Copy link

s2tephen commented Sep 26, 2017

Certain colors (I've only seen this in HSL so far) don't round correctly when calling string().

For example:

var Color = require('color');

var pink = Color('#FF08C2');
console.log(pink.hsl().string()); // 'hsl(314.79999999999995, 100%, 51.6%)'
@jacksenior
Copy link

Observed when using RGBA
color('#000').fade(0.9).string();
returns "rgba(0, 0, 0, 0.09999999999999998)"

@Qix-
Copy link
Owner

Qix- commented Feb 24, 2018

Which version of color?

@henopied
Copy link

henopied commented Mar 11, 2018

@Qix- This issue can be observed in node 9.8.0 and with color 3.0.0. This is due to floating point error. There are different ways of dealing with this, possibly using toPrecision.

@Qix-
Copy link
Owner

Qix- commented Mar 12, 2018

@henopied Aware it's a rounding problem. I thought it was fixed in color-string, though. Let me investigate.

@astrotim
Copy link

Any news on this issue?

filipekiss referenced this issue in filipekiss/stylelint-color-format Oct 23, 2018
 - Ensure HEX color in shorthand properties are properly parsed/fixed
 - Return rounded values for HSL. This is due to a bug in
 `color-string` See issue #2 and Qix-/color#127

 Resolve #2 Fixes #3
@iamgoodbytes
Copy link

Possibly related. Alpha value don't seem to get rounded

rgba(47, 64, 85, 0.0784313725490196)
hsla(213, 29%, 26%, 0.0784313725490196)

I agree that my input values might be a bit weird but the figma API is returning them unrounded as well.

@Nantris
Copy link

Nantris commented Nov 10, 2019

This feature would be really great. I don't know why fading a color by 0.8 returns a color with a valpha of 0.19999999999999996, but when you've got a lot of colors that end up like this it gets pretty messy to look at.

fade(0.8) >>> valpha = 0.19999999999999996
fade(0.7) >>> valpha = 0.30000000000000004

Everything else I've tried has returned a round number as expected.

@Qix-
Copy link
Owner

Qix- commented Nov 10, 2019

@slapbox please read this article before complaining about your particular case of rounding. That's not what the OP is facing, per se.

@Nantris
Copy link

Nantris commented Nov 11, 2019

@qix it's a rounding error nonetheless. Would you prefer I open a new issue then?

@Qix-
Copy link
Owner

Qix- commented Nov 12, 2019

@slapbox No, because the rounding error you're reporting is only fixable by the IEEE. Feel free to open a bug report regarding the IEEE-754 standard.

@Nantris
Copy link

Nantris commented Nov 12, 2019

@Qix- I understand calculations are done with floating points, but surely you're not telling me that we can't round 0.19999999999999996 when we're done with calculations and getting a string value with .rgb().string().

@Qix-
Copy link
Owner

Qix- commented Nov 13, 2019

@slapbox I'm not sure why you're pushing so hard on this. Yes it can be rounded, I just want to make sure you understand where your errors are coming from as opposed to OP's.

@gordonnl
Copy link

gordonnl commented Mar 5, 2021

Have their been any decisions made on this issue? Still occurring in 3.1.3

@bbugh
Copy link

bbugh commented Jun 29, 2021

It's not just alpha, hue is not rounded in certain conditions. For example, converting tomato to hsl even with round() or round(1) or no round results in unrounded hue:

Color('tomato').hsl().round().string()  === "hsl(9.100000000000023, 100%, 63.9%)"
Color('tomato').hsl().round(1).string() === "hsl(9.100000000000023, 100%, 63.9%)"
Color('tomato').hsl().round(5).string() === "hsl(9.100000000000023, 100%, 63.9%)"
Color('tomato').hsl().string()          === "hsl(9.100000000000023, 100%, 63.9%)"

This happens in 3.1.3.

@stevage
Copy link

stevage commented Mar 31, 2022

The bug is that the library is taking a floating point number, using toFixed() to convert it to a rounded number in string form, then immediately converting back into a floating point number again.

		return new Color(this.color.map(roundToPlace(places)).concat(this.valpha), this.model);

and

let self = this.model in colorString.to ? this : this.rgb();
self = self.round(typeof places === 'number' ? places : 1);
const args = self.valpha === 1 ? self.color : self.color.concat(this.valpha);
return colorString.to[self.model](args);

The rounding needs to happen at the last minute when the result is passed back to the caller of .string() or .hex() etc.

(Nothing to do with the IEEE.)

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

No branches or pull requests

10 participants