- From: Oriol Brufau via GitHub <sysbot+gh@w3.org>
- Date: Thu, 30 Jan 2020 22:01:26 +0000
- To: public-css-archive@w3.org
Loirooriol has just created a new issue for https://github.com/w3c/csswg-drafts: == [css-values] round(A,B) with B negative == When rounding a value A with a negative precision B, I think there are two reasonable approaches: 1. Ignore the sign, so that ``` round(nearest, A, -B) = round(nearest, A, B) round(up, A, -B) = round(up, A, B) round(down, A, -B) = round(down, A, B) round(to-zero, A, -B) = round(to-zero, A, B) ``` We find the two integer multiples of B closest to A, "lower B" and "upper B", with "lower B" < "upper B". And then we choose between by applying the strategy to "lower B" and "upper B": - For `nearest`, choose whichever of "lower B" and "upper B" that is closer to A. In case of tie, choose "upper B". - For `up`, choose "upper B". - For `down`, choose "lower B". - For `to-zero`, choose whichever of "lower B" and "upper B" that is closer to 0. In JS, for finite B, ``` round(nearest, A,B) = Math.round(A/Math.abs(B)) * Math.abs(B) round(up, A,B) = Math.ceil(A/Math.abs(B)) * Math.abs(B) round(down, A,B) = Math.floor(A/Math.abs(B)) * Math.abs(B) round(to-zero, A,B) = Math.trunc(A/Math.abs(B)) * Math.abs(B) ``` 2. Use the sign to reverse the strategy, so that ``` round(nearest, A, -B) = -round(nearest, -A, B) round(up, A, -B) = round(down, A, B) round(down, A, -B) = round(up, A, B) round(to-zero, A, -B) = round(to-zero, A, B) ``` We find the two integer multiples of B closest to A, `B*n` and `B*(n+1)`. And then we choose between them by applying the strategy to `n` and `n+1`: - For `nearest`, choose whichever of `B*n` and `B*(n+1)` that is closer to A. In case of tie, choose `B*(n+1)`. - For `up`, choose `B*(n+1)`. - For `down`, choose `B*n`. - For `to-zero`, choose `B*n` if `n` is closer to 0 than `n*1`, else `B*(n+1)`. In JS, for finite B, ``` round(nearest, A,B) = Math.round(A/B) * B round(up, A,B) = Math.ceil(A/B) * B round(down, A,B) = Math.floor(A/B) * B round(to-zero, A,B) = Math.trunc(A/B) * B ``` Note there is no difference for `to-zero`. And for `nearest` it only matters in case of tie. Currently the spec defines [`round()`](https://drafts.csswg.org/css-values-4/#round-func) with (1). However, later it seems to assume (2): > `mod()` and `rem()` can also be defined directly in terms of other functions: `mod(A, B)` is equivalent to `calc(A - round(down, A, B))`, while `rem(A, B)` is equivalent to `calc(A - round(to-zero, A, B))`. The former doesn't hold with (1), e.g. `mod(3, -2)` is supposed to be `-1`, but `3 - round(down, 3, -2)` is `3 - 2 = 1`. But it works with (2): `3 - 4 = -1`. With (1), I guess the quote should say `(A - round(down, A, B)) * sign(B)` So either keep the definition of round() as-is and fix the quote, or change the definition of round() and keep the quote. And add a note. Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/4718 using your GitHub account
Received on Thursday, 30 January 2020 22:01:27 UTC