Open
Bug 1163047
Opened 10 years ago
Updated 2 years ago
CSS tokenizer and JS disagree about interpretation of "1.45"
Categories
(Core :: CSS Parsing and Computation, defect)
Tracking
()
NEW
People
(Reporter: tromey, Unassigned)
Details
A devtools test caught the fact that the CSS tokenizer converts
the token "1.45" to a number which is later printed as "1.4500000476837158".
On the other hand, JS's parseFloat successfully round-trips "1.45" -> "1.45".
(I didn't examine the underlying bits to see exactly how they differ in interpretation.)
It would be handy for devtools if CSS and JS agreed on conversion of floating point
values.
I am wondering whether it would be possible to make nsCSSScanner::ScanNumber
use js_strtod for floating-point numbers.
Reporter | ||
Comment 1•10 years ago
|
||
There's this: http://dev.w3.org/csswg/css-syntax/#convert-a-string-to-a-number
But that doesn't actually specify how one would convert to a double.
It just specifies the meaning in some abstract way -- so I think there's
nothing in the standard preventing this. And in fact the JS way is
better than what is done now, see the Clinger paper it is based on:
http://www.cesura17.net/~will/Professional/Research/Papers/howtoread.pdf
![]() |
||
Comment 2•10 years ago
|
||
> On the other hand, JS's parseFloat successfully round-trips "1.45" -> "1.45".
Does it? 1.45 is not exactly representable, so what you're seeing there is that the double-to-string conversion is rounding to 1.45. In particular:
parseFloat("1.45").toPrecision(21)
"1.44999999999999995559"
So that's issue number 1. But more importantly, issue number 2 is that the CSS scanner output is a _float_, not a double. Here's a simple C test program:
float f = 1.45;
double d = 1.45;
printf("%.20f\n", f);
printf("%.20f\n", d);
and the output is:
1.45000004768371582031
1.44999999999999995559
which is exactly what you see (for the first one) and what JS outputs (for the second one).
> And in fact the JS way is better than what is done now
Better in what way? The only relevant metric is "faster", since they're equally accurate in this case: the CSS scanner does the conversion into a double, then converts that to float, so the difference between 0.97 units in the last mantissa bit and 0.5 units in the last mantissa bit (of the double) discussed in the paper you link to is not so relevant once the rounding to float happens.
Going back to the main ask, though, getting JS and CSS to agree on conversion of floating point values is just impossible if JS is using doubles and CSS is using floats.
Reporter | ||
Comment 3•10 years ago
|
||
Also I see that nsCSSToken::mNumber is a float, not a double.
So perhaps we'd want to change this to double for JS's sake,
and let the double->float conversion happen in other users of the field.
![]() |
||
Comment 4•10 years ago
|
||
Oh, and note that this is not exactly web-observable, since access to the value via CSSOM (whether specified style or computed style) will use AppendFloat, which does float-to-string conversion (as opposed to the float to double to string conversion that was done in comment 0, presumably), so things will get rounded to "1.45" correctly.
![]() |
||
Comment 5•10 years ago
|
||
> Also I see that nsCSSToken::mNumber is a float, not a double.
Yes, precisely.
I guess we don't have too many nsCSSTokens around, so using a double there might be ok... Note that this will mean that in some cases what your JS-exposed tokenizer sees won't match what actually gets stored in Gecko, of course.
Reporter | ||
Comment 6•10 years ago
|
||
(In reply to Not doing reviews right now from comment #2)
> But more importantly, issue number 2 is that the
> CSS scanner output is a _float_, not a double.
Yes, I realized this eventually.
> Going back to the main ask, though, getting JS and CSS to agree on
> conversion of floating point values is just impossible if JS is using
> doubles and CSS is using floats.
It seems you're correct and that all that matters is the float.
That makes this much simpler then.
Reporter | ||
Comment 7•10 years ago
|
||
(In reply to Not doing reviews right now from comment #5)
> > Also I see that nsCSSToken::mNumber is a float, not a double.
>
> Yes, precisely.
>
> I guess we don't have too many nsCSSTokens around, so using a double there
> might be ok... Note that this will mean that in some cases what your
> JS-exposed tokenizer sees won't match what actually gets stored in Gecko, of
> course.
Yeah, I am not sure if this matters.
I will have to dig a bit more to find out, thanks for the note.
Comment 8•9 years ago
|
||
Is this actionable at all?
Reporter | ||
Comment 9•9 years ago
|
||
(In reply to Florian Bender from comment #8)
> Is this actionable at all?
It seems feasible to change the lexer to use doubles
and expose those via CSSLexer to JS. This would fix the lexing case,
but you could still see discrepancies.
Devtools has since moved to a pure JS CSS lexer so this isn't a need there any more.
![]() |
||
Comment 10•9 years ago
|
||
If devtools is not using this stuff, do we need it at all?
Updated•2 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•