Skip to content

fix(HF-162): scale TEXT percentage formats before rounding - #1776

Open
Tobiadefami wants to merge 2 commits into
developfrom
fix/HF-162
Open

Tobiadefami wants to merge 2 commits into
developfrom
fix/HF-162

Conversation

@Tobiadefami

@Tobiadefami Tobiadefami commented Sep 17, 2026 •

Copy link
Copy Markdown
Collaborator

Context

TEXT(0.0123,"0.00%") currently returns 0.01% instead of Excel's 1.23% because the built-in number formatter rounds before applying percentage scaling. This PR fixes the reported behavior in #1565.

Changes

  • Treat each unquoted, unescaped % in a numeric mask as an operator that multiplies the value by 100 before rounding. Quoted and escaped percent signs remain literal.
  • Return #VALUE! if percentage scaling overflows, matching the observed Excel behavior.
  • Update the changelog and Excel compatibility guide. Existing workbooks that multiply by 100 to work around the old behavior can remove that workaround after this fix lands.

Merge order

Formatter PR #1716 rewrites the same parser and renderer on a section-based architecture. As Marcin recommended, #1716 should land first. I will then port this percentage behavior to its formatter, reconcile the compatibility guide, and rerun the paired tests before this PR merges. The current head still implements the fix on the pre-#1716 formatter.

How did you test your changes?

  • The paired test suite (hyperformula-tests Global settings #58): 83/83 tests passed at the current head in review; reverting this source change made 22 of them fail.
  • After the final runtime correction, the full Jest run passed 503 suites (6,266 tests passed; 3 skipped), TypeScript compilation passed, and touched-file lint passed with zero errors.
  • Compared 20 percentage, rounding, literal-percent, and overflow cases with Excel Online; the corrected results matched.

Types of changes

  • Breaking change
  • New feature or improvement
  • Bug fix
  • Additional language file or translation change
  • Documentation change

Related issues

Checklist

  • I have reviewed the contribution guidelines and confirmed the code follows the project style.
  • I have signed the Contributor License Agreement.
  • The change is compliant with OpenDocument 1.3.
  • The change is compatible with Microsoft Excel.
  • The change is compatible with Google Sheets.
  • I described the change in CHANGELOG.md.
  • Documentation has been updated.
  • A migration guide is required.

Note

Medium Risk
Changes default TEXT output for % formats (behavior fix aligned with Excel), which may affect spreadsheets that relied on the old scaling or manual *100 workarounds.

Overview
Fixes TEXT percentage number formats so they match Excel: each active % in the format string multiplies the numeric value by 100 before rounding, so TEXT(0.0123,"0.00%") returns 1.23% instead of 0.01%.

The number-format parser now tokenizes %, quoted literals, and escapes separately (quoted or escaped % stay literal and do not scale). numberFormat applies scaling once per percent token, surfaces #VALUE! if scaling overflows, and appends % in the output. CHANGELOG and the Excel compatibility guide document the behavior and note that workarounds that manually multiply by 100 can be removed.

Reviewed by Cursor Bugbot for commit 0a2fb42. Bugbot is set up for automated code reviews on this repo. Configure here.

@cla-external-contractor-signup

Copy link
Copy Markdown

@Tobiadefami thanks for the pull request. No CLA step needed here — our records show you signed the Contributor License Agreement on 2026-07-31. That signature came from our previous signing form and has been carried over, so there is nothing for you to re-sign.

@qunabu

qunabu commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit eb63d50. Configure here.

Comment thread CHANGELOG.md Outdated
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
hyperformula-docs 0a2fb42 Commit Preview URL

Branch Preview URL
Sep 17 2026, 10:11 PM

@github-actions

github-actions Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Performance comparison of head (0a2fb42) vs base (c920375)

                                     testName |   base |    head | change
-------------------------------------------------------------------------
                                      Sheet A | 482.34 |  488.46 | +1.27%
                                      Sheet B | 152.44 |  152.68 | +0.16%
                                      Sheet T | 135.22 |  135.67 | +0.33%
                                Column ranges | 467.12 |  463.18 | -0.84%
                                Sorted lookup |  14585 | 13705.9 | -6.03%
Sheet A:  change value, add/remove row/column |  14.65 |      14 | -4.44%
 Sheet B: change value, add/remove row/column | 129.07 |  132.22 | +2.44%
                   Column ranges - add column | 147.94 |  142.81 | -3.47%
                Column ranges - without batch | 447.41 |  437.34 | -2.25%
                        Column ranges - batch |  114.4 |  108.21 | -5.41%

@marcin-kordas-hoc marcin-kordas-hoc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Recommendation: Request changes — hold for merge-order, not for correctness.

The percent-scaling fix itself is solid. I reproduced the reported defect on develop
(TEXT(0.0123,"0.00%") returned 0.01% instead of 1.23% — off by 100x) and confirmed it's
fixed at this PR's head (1.23%). The paired test suite (hyperformula-tests #58) passes 83/83,
and reverting the source change while keeping the tests fails 22 of them, so the suite genuinely
discriminates fixed from unfixed behavior. Measured via MS Graph against a live Excel Online
session (pl-PL locale): once the format masks are written in valid pl-PL syntax (comma as decimal
separator — a .-based mask errors under this locale regardless of percent, which is worth
knowing but is unrelated to this PR), Excel's output matches this fix's output across rounding,
sign handling, zero, and overflow.

The reason I can't approve as-is: this PR modifies numberFormat() and the number-format
tokenizer (matchNumberFormat()) in src/format/format.ts / parser.ts, and the already-approved
#1716 rewrites those same two functions on an incompatible architecture (a Config-driven,
section-based renderer vs. this PR's percent-scaling loop on the old signature). A test merge of
the two produces real conflicts in both source files and in the compatibility guide — not a
rebase-and-resolve, since the two designs overlap on the same functions. Since #1716 is approved
and further along, I'd suggest it lands first, and this PR's percent-scaling logic gets
re-implemented on top of its section-based formatter rather than carried over as-is. As part of
that: this PR's new doc paragraph says percentage formats like 0.00% are supported, directly
above the sentence #1716 rewrites to say the opposite — that sentence doesn't exist yet on this
branch, so the contradiction will need a manual edit at merge time either way.

@Tobiadefami

Copy link
Copy Markdown
Collaborator Author

@marcin-kordas-hoc Agreed. Let's wait for #1716 to land, then I'll port the percentage scaling to its section-based formatter, reconcile the compatibility guide, and rerun the paired test suite (hyperformula-tests #58) before requesting another review. I've updated this PR's description to reflect that merge order. Thanks for the thorough review.

@codecov

codecov Bot commented Sep 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.32%. Comparing base (c920375) to head (0a2fb42).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop    #1776   +/-   ##
========================================
  Coverage    97.32%   97.32%           
========================================
  Files          195      195           
  Lines        15739    15758   +19     
  Branches      3390     3468   +78     
========================================
+ Hits         15318    15337   +19     
+ Misses         421      413    -8     
- Partials         0        8    +8     
Files with missing lines Coverage Δ
src/format/format.ts 99.37% <100.00%> (+0.02%) ⬆️
src/format/parser.ts 100.00% <100.00%> (ø)

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

3 participants