Skip to content

Prevent fused arithmetic from changing round results - #488

Open
cl2t wants to merge 1 commit into
Masterminds:masterfrom
cl2t:fix-round-fma
Open

cl2t wants to merge 1 commit into
Masterminds:masterfrom
cl2t:fix-round-fma

Conversation

@cl2t

@cl2t cl2t commented Sep 22, 2026 •

Copy link
Copy Markdown

With Go 1.26.3 on arm64 and Go 1.27.1 on riscv64, round(123.5555, 3) can return 123.555 instead of 123.556. After math.Modf is inlined, a fused multiply-subtract retains extra precision and moves the fractional part below the rounding threshold.

Explicitly convert the product to float64 so it is rounded before Modf subtracts its integer part, as required by the Go floating-point rules.

Validation:

  • On current master (989da45), the existing TestRound fails before this change and passes afterward with Go 1.26.3 on darwin/arm64.
  • The full upstream suite passes with TZ=UTC (the existing TestHtmlDate expects that date). Dependencies were tested offline using a temporary modfile pointing to the official cast v1.9.2 archive; repository module files are unchanged.
  • The same fix passes the v2.22.0 suite in openRuyi with Go 1.27.1 on x86_64 and riscv64; only the network-dependent DNS test is excluded there.

Assisted-by: Codex:GPT-6

When Modf is inlined, a fused multiply-subtract can retain extra
precision from pow * val and move a half-way fractional part below 0.5.
On arm64 and riscv64, round(123.5555, 3) then returns 123.555 instead
of 123.556.

An explicit float64 conversion rounds the product before Modf examines
it. The existing TestRound case covers the regression.

Signed-off-by: cl2t <yihong.or@isrc.iscas.ac.cn>

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.

1 participant