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

Support number format digit options for PluralRules #3929

Open
hsivonen opened this issue Aug 24, 2023 · 9 comments
Open

Support number format digit options for PluralRules #3929

hsivonen opened this issue Aug 24, 2023 · 9 comments
Assignees
Labels
C-pluralrules Component: Plural rules S-medium Size: Less than a week (larger bug fix or enhancement) T-core Type: Required functionality U-ecma402 User: ECMA-402 compatibility

Comments

@hsivonen
Copy link
Member

Currently, the options from https://tc39.es/ecma402/#sec-setnfdigitoptions are unsupported. These are:

  • minimumIntegerDigits
  • minimumFractionDigits
  • maximumFractionDigits
  • minimumSignificantDigits
  • maximumSignificantDigits
  • roundingPriority
  • roundingIncrement
  • roundingMode
  • trailingZeroDisplay

These need to be supported for ECMA-402 compat.

@hsivonen hsivonen added C-pluralrules Component: Plural rules U-ecma402 User: ECMA-402 compatibility labels Aug 24, 2023
@sffc
Copy link
Member

sffc commented Aug 24, 2023

We support these already:

  • minimumIntegerDigits
  • minimumFractionDigits
  • maximumFractionDigits
  • roundingMode

The following can be implemented fairly easily in wrapper code, but it may still be useful to move them into the library:

  • minimumSignificantDigits
  • maximumSignificantDigits
  • roundingPriority
  • trailingZeroDisplay

The following is less trivial to implement in user code so should definitely land in ICU4X:

  • roundingIncrement

@sffc
Copy link
Member

sffc commented Aug 26, 2023

I made an issue #3942 in order to make an API that more directly handles the rounding-related ECMA-402 options listed above (which I think is all but trailingZeroDisplay).

@sffc sffc self-assigned this Sep 21, 2023
@sffc sffc added this to the 1.x Priority ⟨P2⟩ milestone Sep 21, 2023
@sffc sffc added the S-medium Size: Less than a week (larger bug fix or enhancement) label Sep 21, 2023
@sffc
Copy link
Member

sffc commented Sep 21, 2023

@sffc to write a design doc for this and for #3942

@sffc sffc added the T-core Type: Required functionality label Sep 21, 2023
@jedel1043
Copy link
Contributor

jedel1043 commented Oct 22, 2023

FWIW, most of the options were very straightforward to apply:

https://github.com/boa-dev/boa/blob/caac9049c40f7361ede282cf358d3c5981e5d6db/boa_engine/src/builtins/intl/number_format/utils.rs#L274-L301

However, I couldn't find a way to apply the roundingIncrement option without support for division from FixedDecimal, which would let me do:

let increment: FixedDecimal = FixedDecimal::from(_rounding_increment).multiplied_pow10(-max_fraction);
number /= increment;
round(number, 0, rounding_mode);
number *= increment;

and that is essentially what ICU4C does:

https://github.com/unicode-org/icu/blob/c4689841c001a0b98e5b59adaab34656bd2a998f/icu4c/source/i18n/number_decimalquantity.cpp#L202-L208

@sffc
Copy link
Member

sffc commented Oct 24, 2023

Yeah, roundingIncrement in ECMA-402 is limited to common integer values that evenly divide the next highest power of 10 (like 20, 25, and 50). This is in part to enable a more efficient implementation in libraries like ICU4X, avoiding the need for division.

It would be an excellent first issue for someone to write the following API:

pub enum RoundingIncrement {
    I1, I2, I5, I10, I20, I25, I50, I100, I200, I250, I500, I1000, I2000, I2500, I5000
}

impl FixedDecimal {
    pub fn round_half_even_with_increment(&mut self, position: i16, increment: RoundingIncrement) { ... }
}

Come to think of it, we should really only need I2, I5, and I25. The expressiveness of the FixedDecimal API in ICU4X allows all of the others to be derived.

@sffc
Copy link
Member

sffc commented Oct 26, 2023

Discussion from team meeting on 2023-10-26:

  • @sffc - other option to have multiple methods: trunc_to_multiple_of_5
  • @sffc - RoundingIncrement is used in Ecma and ICU4C
  • @sffc - trunc_to_multiple, with enum Multiple {...}
  • @robertbastian - I don't like being constrained by Ecma or ICU4C naming on our API design
  • @sffc - I think niche concepts should have consistent naming because it helps make concepts more transferrable. For higher-level things, if we can shape an API significantly better, then we can diverge.
  • @robertbastian - niche APIs don't affect as many users, so in a way less problematic to use different names/concepts
  • @sffc - Multiple functions could be trunc_to_increment_of_5, or trunc_to_incr_5
  • @robertbastian - should be trunc_to_increment_of_multiples_of_5 then
  • @sffc - trunc_to_increment with enum RoundingIncrement?
  • @robertbastian - I'm not opposed to that suggestion and not particularly attached to any other suggestion that's been made.

Conclusion: trunc_to_increment(-2, RoundingIncrement::MultiplesOf5)

LGTM: @sffc (@robertbastian) (@Manishearth)

Enum values:

enum RoundingIncrement {
    #[default]
    MultiplesOf1,
    MultiplesOf2,
    MultiplesOf5,
    MultiplesOf25,
}

LGTM: @sffc @robertbastian (@Manishearth)

@sffc
Copy link
Member

sffc commented Oct 31, 2023

@jedel1043 merged trunc_to_increment in #4219 (thanks, it looks great!). The next step is to add expand_to_increment, which may be slightly trickier but should come out looking fairly similar to #4219. Then we can add all the other functions which currently delegate to either trunc or expand (we may need to slightly change how they decide which one to delegate to).

Another thing I'd like us to measure is whether the new rounding increment code has an impact on the performance of the trunc function in the common case of no rounding increment.

@jedel1043
Copy link
Contributor

jedel1043 commented Oct 31, 2023

Just wanted to notify that I have in the queue a PR for expand_to_increment and a PR for the remaining methods. I'm currently testing the edge cases of expand_to_increment and the rest of the methods, but the core functionality should be done. I'll probably open a PR in the next few days.

@sffc
Copy link
Member

sffc commented Oct 31, 2023

Fantastic!

Just to highlight as part of your testing in the expand_to_increment function: we had issues previously regarding the expand function and rounding up numbers with interior zeroes; see #3644.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-pluralrules Component: Plural rules S-medium Size: Less than a week (larger bug fix or enhancement) T-core Type: Required functionality U-ecma402 User: ECMA-402 compatibility
Projects
None yet
Development

No branches or pull requests

3 participants