Skip to content

Use Intl mathematical values in ConvertUnitValue - #125

Draft
jessealama wants to merge 14 commits into
mainfrom
convertto-mathematical-values
Draft

jessealama wants to merge 14 commits into
mainfrom
convertto-mathematical-values

Conversation

@jessealama

Copy link
Copy Markdown
Collaborator

Related to #115 , use (Intl) mathematical values in ConvertUnitValue to remove at least one step of rounding. Before:

Return _value_ × 𝔽(_sourceFactor_ / _targetFactor_)

Now:

Return 𝔽(ℝ(_value_) × _sourceFactor_ / _targetFactor_):

@jessealama
jessealama requested a review from eemeli June 24, 2026 12:46
@github-actions

github-actions Bot commented Jun 24, 2026 •

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://tc39.github.io/proposal-amount/pr-preview/pr-125/

Built to branch gh-pages at 2026-10-02 02:53 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@gibson042 gibson042 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought there was too much resistance to mathematical-value multiplication and division, but am happy if that's not the case.

Comment thread spec.emu Outdated
Comment thread spec.emu Outdated
Comment thread spec.emu Outdated
Comment thread spec.emu Outdated
Comment thread spec.emu Outdated
Comment thread spec.emu Outdated

@sffc sffc left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With #115, not all results become exact; for example, 0.3𝔽 * 3 still equals 0.8999999999999999𝔽. I think the way to specify this is to use Math.fma.

EDIT: This example is describing what the behavior should be, which is not what this PR specifies.

@gibson042

Copy link
Copy Markdown
Member

With #115, not all results become exact; for example, 0.3𝔽 * 3 still equals 0.8999999999999999𝔽. I think the way to specify this is to use Math.fma.

Where in the changes of this PR do you see any step that could result in that calculation?

@sffc

sffc commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

With #115, not all results become exact; for example, 0.3𝔽 * 3 still equals 0.8999999999999999𝔽. I think the way to specify this is to use Math.fma.

Where in the changes of this PR do you see any step that could result in that calculation?

This PR appears to do all math in MV space, including converting a float to an Intl MV, which treats the float as the shortest decimal, not the full-precision floating point MV. However, that cannot be implemented without decimal arithmetic, which is a hard no from engines. The approach in #115 is a compromise that gets us closer to exact arithmetic by removing the double-rounding in a * b / c but still allowing it to be done using floats.

@eemeli eemeli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like quite a surprising change, and would require explicit implementer approval before we apply it. Introducing a requirement for an implementation to be able to do decimal multiplication is... a lot. And rather like with Math.fma(), it's a capability that, if approved, should not only be available in this one corner of the spec.

So if you would like us to do this, I think you need to first present a separate proposal introducing that capability to the language, and then we use it here.

@jessealama

Copy link
Copy Markdown
Collaborator Author

The thinking behind these changes was to imagine a world where we had Math.fma so the Number-based calculations offered by Amount would be, effectively, as good as it gets. The idea is that moving (more of) the calculations to mathematical values, as done here, captures that intent without actually using Math.fma in the spec text. But it sounds like what I'm up to here is going beyond what Math.fma can offer. At a minimum, an argument needs to be made for that proposition. I'll keep this PR open but mark it as a draft, for now, and will tackle the rounding issues in a separate PR using Math.fma. If that PR looks good, we can close this one.

@jessealama
jessealama marked this pull request as draft June 25, 2026 09:19
@jessealama
jessealama force-pushed the convertto-mathematical-values branch from 642ff63 to 865de77 Compare June 25, 2026 09:27
@sffc

sffc commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

But it sounds like what I'm up to here is going beyond what Math.fma can offer.

Right. We can't require implementors to do more than Math.fma can offer.

@sffc

sffc commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Let me qualify that comment: The objective of FMA is to avoid multi-rounding of floats. It might be possible to specify that behavior without using Math.fma, so long as it is done carefully.

See some of my more recent comments in #115.

@jessealama
jessealama force-pushed the convertto-mathematical-values branch from 865de77 to 97bbd42 Compare October 2, 2026 02:39
jessealama and others added 5 commits October 2, 2026 04:45
Co-authored-by: Richard Gibson <richard.gibson@gmail.com>
Co-authored-by: Richard Gibson <richard.gibson@gmail.com>
ConvertUnitValue now takes an Intl MV Record and returns one, so the
operation's header and its two callers agree with the algorithm body.
The variable name in the offset branch and the missing underscores on
the result variable are fixed along the way.
ConvertUnitValue relies on positive factors to preserve negative zero in
the purely multiplicative case. Nothing in the CLDR conversion data
promises that, so state the assumption as an assertion.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants