-
Notifications
You must be signed in to change notification settings - Fork 3
Rationals #23
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
Comments
I'm among the delegates that would see It's also possible that a Rational could additionally cover a Ratio if the components are Amounts rather than just Decimals...
This would be an extremely elegant approach for a broad range of use cases. |
I'm a bit skeptical about the use cases for rational numbers in JavaScript, and would like to see examples of real-world code that currently needs to do something un-ergonomic to work with them. The one case I'm aware of is cooking recipes that feature US units like "⅓ cup" that want to allow for a toggle converting the units to or from metric units like "80 ml", but are there other places where rationals are currently used? I would be particularly interested to hear of cases where the source data is a rational value, rather than the rational-ness only being an aspect of the value's formatting. |
The results of unit conversions in CLDR are represented as rationals, and ICU4X implements it using rationals.
In the same way that 1 != 1.0 for i18n concerns, 1.3333 != 4/3 != 1 1/3. |
It seems likely that rationals, at least the i18n side of them, can be handled with a decimal (or even float) data model. Bear with me here: There would be an enumeration, perhaps "RatioStyle", with the following values:
Example behavior:
With this approach, I think we also need a few more dimensions:
It occurs to me that "what denominators are allowed" is context-sensitive. Thirds and sixths are things I've seen in cooking, but not in rulers or person height, for example. I think this type of approach is a bit complex but might result in a more narrow and correct solution, at least for the i18n use case of rationals. |
It's also worth noting that fraction.js, just one module on npm dealing with rational numbers, sees about 17 million downloads per week and 500+ direct dependent modules. https://www.npmjs.com/package/fraction.js ... Which is just to say the use cases do exist. Whether they are enough to justify Rational is obviously up for discussion. |
Following up from an interesting conversation with @michaelficarra, @mikbar-uib I asked whether there was a fixed set of denominators for rationals that cover all non-arithmetic use cases. It seems that the ones listed above are most common (powers of 2 up to maybe 1024 and small integers less than about 10). However, there are ratios that show up in the wild that can be quite surprising, such as To generalize to arbitrary denominators, the approach I've described about picking the canonical decimal for a floating point value (tc39/proposal-decimal#181, Lxxyx/proposal-number-is-safe-numeric#3) can also be applied to rationals. The algorithm would be, just, what is the rational with the smallest denominator that maps to the exact bucket? I wrote some code to evaluate how often we get collisions. I have to make the denominator fairly large before I get a true conflict, such as |
I discussed this with the CLDR Design WG. In general it seems that rational formatting could be feasible but it needs a lot of homework to be done. CLDR is not interested in doing that homework unless there is a clear user need. TC39 saying that we need this is some evidence, but ideally we have specific clients illustrating the need, especially for end users outside of |
I haven't seen discussion of what the format would look like outside of ASCII digits and their precomposed forms. In Tamil for example 𑿇 is 3⁄64 — That's just to give an example of the kind of homework needed. Note that I used the fraction slash U+3044, try viewing this comment in Firefox if you're not already there. |
Some discussion in this CLDR issue: https://unicode-org.atlassian.net/browse/CLDR-17570 |
Linking in an issue in the decimal repo where we discussed rationals. |
Another alternative data model could be, more simply, bigint over bigint rather than Decimal128 over Decimal128. This has the disadvantage that the data model is inherently unbounded, though there may be some advantages. Some reasonable normalizations (done during construction or perhaps lazily if some operations get called) might be:
|
Rational numbers are compatible with an opaque Amount.
The data model could be "decimal over decimal integer", where a decimal integer is the set of all Decimal128 that are integer values.
Example data models to what they represent:
(2.50 / 1) inch
==> 2.50 inches(5 / 2) inch
==> 5/2 inches(5 / 2) integral-inch
==> 2 1/2 inchesThis can be added on to an opaque Amount.
Alternatively, this could be a core part of the proposal, since some delegates see rationals as well-motivated, and this is a clean way to add them: arithmetic is very likely out of scope of Amount, so we remove a whole class of issues.
The text was updated successfully, but these errors were encountered: