sass icon indicating copy to clipboard operation
sass copied to clipboard

Use floating-point numbers universally

Open connorskees opened this issue 5 years ago • 3 comments

Currently the to and from values for @for are unbounded and not formally defined.

This input is considered valid Sass,

@for $i from -999999999999999999999 to 999999999999999999999999 { ... }

In order to simplify implementations, I would like to propose the bounding of these values.

I believe the easiest solution would be to use a 32 bit signed integer in order to represent these bounds. This will provide a reasonable range of values without requiring much work on the part of an implementation.

In order to better avoid overflows, I would like to propose that the max and min values be actually defined as i32::MAX - 1 and i32::MIN + 1 respectively.

More concretely, the maximum value would be 2,147,483,646 and the minimum value would be -2,147,483,647.

It seems that dart-sass today silently overflows for the to and from values at some point. Bounding these in this way would remove this issue altogether.

connorskees avatar Aug 15 '20 23:08 connorskees

This ties in with a broader issue that we should better define how numbers work in Sass. I'm retargeting this to be for the broader issue, since whatever we decide there would probably determine the bounds of @for loops.

From the discussion in sass/dart-sass#807, we're currently leaning towards defining all Sass numbers as floating points (in line with JavaScript and how libsass is currently implemented), so we probably won't define @for in terms of integers of a certain size.

jathak avatar Aug 17 '20 20:08 jathak

the way numbers are implemented in dart-sass regarding the handling of precision and equality (and other operations) looks like it wants to be using fixed point arithmetic rather than floating point arithmetic though.

stof avatar Dec 04 '20 12:12 stof

From https://github.com/sass/sass/issues/3335:

Sass has never clearly specified its internal number format. Ruby Sass inherited Ruby's support for transparently switching to bignums when numbers got extremely large, and Dart Sass did the same thing initially until Dart dropped support for transparent bignums in 2.0.0. LibSass, on the other hand, has only ever used floating point numbers.

Although we could mandate the implementation of transparent bignums, this would add a substantial amount of implementation complexity and performance overhead since we'd have to do bounds-checking for every operation. Instead, I think just standardizing on double-width floating points makes sense, particularly because the compromises inherent in using floating point numbers everywhere are already well-understood by the web community thanks to JS.

Marking this as a bug because the behavior of large numbers is currently inconsistent in a problematic way.

nex3 avatar Jun 15 '22 23:06 nex3

The proposal is now out for review. I'll give it two weeks before we mark it as accepted and move on to implementation.

nex3 avatar Aug 31 '22 21:08 nex3