mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-07 02:51:33 +00:00
fix(calc): apply "Set precision as displayed" in calculation (#1366)
* ft-121.7.9: apply Set precision as displayed in calculation (#1343) With the option on, a formula result (and each element of a spill) is rounded to its cell's number format before it is stored and before other formulas read it. Numbers typed, pasted or reformatted while it is on are rounded at once, and turning it on through formulas.calculationOptions {precisionAsDisplayed} rounds every number constant, as Excel does. The rounding is NumberFormat::round_as_displayed in the numfmt crate, which shares the renderer's digit logic (fixed, scientific, fraction). General, date/time, text, digitless and conditional formats keep the full value, as observed in Excel through COM. Nothing changes when the flag is off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ft-121.7.9: round conditional formats by the sign's section under precision as displayed (#1343) Excel does round formats with a condition when "Set precision as displayed" is on; the PR kept them at full value. Observed through COM with synthetic values (and in gridcraft-corpus excel/precision-displayed/pad-on-conditional-sections.xlsx): conditions are ignored and the sign picks the section, the first for positives and the second for negatives. `[<1]0.00;0` shows 2+1/3 as 2 but stores 2.33, and stores -10/3 as -3. Two more observed details: with a condition and a single number section, negatives keep the full value (`[<1]0.00`), unless an `@` section follows (`[<1]0.00;@` rounds them by the first section); and a completely empty section passes to the next one (`0.0;;0.000` stores -2.333 as -2.333, `;0.0` stores 2.333 as 2.3), for formats with or without a condition. Display is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * engine: recalculate spill anchors when a spill cell is reformatted under precision as displayed round_edited_as_displayed only looked at stored-cell changes, but a spill destination lives in Sheet::spill, so reformatting it (or its row or column) left the anchor out of the changed set and the element unrounded. Add each spill anchor whose range holds a changed cell or a changed row/column style to the changed set. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * numfmt: drop a cast the fraction merge made redundant * precision as displayed: keep locked constants on protected sheets, round new sheets, fix manual-mode comment * precision as displayed: name the input sheet in the new-sheet histogram test * precision as displayed: use six values in the new-sheet histogram test --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c402953828
commit
292b784f02
13 files changed
+770
-51
No files matched your search
@@ -89,7 +89,8 @@ This improves series preparation; it does not change the model-fitting or season
|
||||
| YEARFRAC basis 0, February-end start to day 31 | done: Excel 16.0 returns 31/360 for `YEARFRAC(2021-02-28,2021-03-31,0)` (0.08611111111111111); regression also covers leap day and reversed dates |
|
||||
| Trim references `A1:.E10` (trailing), `A1.:E10` (leading), `A1.:.E10` (both), also on whole rows/columns (`A:.A`) | done; evaluated as `TRIMRANGE(range, code, code)`, adjusted on insert/delete; files store `_xlfn.TRIMRANGE(range,code,code)` (Excel's own file spelling unconfirmed in public docs), `_xlfn._TRO_ALL/_TRO_LEADING/_TRO_TRAILING(...)` read too |
|
||||
| LET, LAMBDA, named LAMBDAs, ISOMITTED, MAP/REDUCE/SCAN/BYROW/BYCOL/MAKEARRAY | done. A LAMBDA that calls itself more than 140 times, or a formula nested past the depth limit, gives `#NUM!` (the target app allows deeper recursion, #1581). Calling a defined name that holds an error value gives that error, not `#NAME?` |
|
||||
| Iterative calculation for circular references | done: with Enable Iterative Calculation on (`formulas.calculationOptions` `{iterative, maxIterations, maxChange}`, saved as `<calcPr iterate iterateCount iterateDelta>`), loops are evaluated again from their previous values (blank = 0) until no cell on a loop changes by Maximum Change or Maximum Iterations is reached; off, cycles give `#CIRC!`. Set in File › Options › Formulas (Enable iterative calculation, Maximum Iterations 1 to 32767, Maximum Change 0 or more; the two fields are disabled while iteration is off). Differences: GridCraft recalculates on open, so a loop that never settles (`=A1+1`) advances again each time the file is opened
|
||||
| Set precision as displayed | done: with the option on (`formulas.calculationOptions` `{precisionAsDisplayed}`, read and saved as `<calcPr fullPrecision="0">` and the `.xls` CalcPrecision record), a formula result, each element of a spill, and a number typed or reformatted are stored as the cell's number format shows them, and other formulas read the rounded value. Fixed decimals, percent, thousands scaling (`0.0,,`), fractions and scientific formats round; General, date and time, text and digitless formats keep the full value, as observed in Excel. Conditions don't pick the section that rounds: the sign does, the first section for positives and the second for negatives, so `[<1]0.00;0` stores 2+1/3 as 2.33 though it shows `2`, and -10/3 as -3; with a condition and a single number section, negatives keep the full value; a completely empty section (`0.0;;0.000`) passes to the next. Turning it on rounds every number constant (permanently); turning it off restores formulas only. Differences: Excel also rounds General constants it shows in scientific notation when the option is turned on (GridCraft leaves General alone); a `%` inside a scientific format is left unrounded; no Options dialog checkbox yet (command only) |
|
||||
| Iterative calculation for circular references | done: with Enable Iterative Calculation on (`formulas.calculationOptions` `{iterative, maxIterations, maxChange}`, saved as `<calcPr iterate iterateCount iterateDelta>`), loops are evaluated again from their previous values (blank = 0) until no cell on a loop changes by Maximum Change or Maximum Iterations is reached; off, cycles give `#CIRC!`. Set in File › Options › Formulas (Enable iterative calculation, Maximum Iterations 1 to 32767, Maximum Change 0 or more; the two fields are disabled while iteration is off). Differences: GridCraft recalculates on open, so a loop that never settles (`=A1+1`) advances again each time the file is opened |
|
||||
| 15-significant-digit comparison semantics | done (#57): `=0.1+0.2=0.3` is TRUE, and MATCH and COUNTIF compare the same way. Arithmetic keeps full precision, as Excel does — `=(0.1+0.2)-0.3` is 5.55E-17 |
|
||||
| IMSQRT and the other IM* functions against Excel's text | IMSQRT follows Excel's polar route, so a negative real gives Excel's stray real part: `IMSQRT("-4")` is `1.22514845490862E-16+2i` (checked in Excel 16.0 on 79 inputs). Differences kept: IMSQRT of a number with a part above about 1E154 or below about 1E-155 gives the exact root (Excel gives `#NUM!` or 0); IMPOWER, IMEXP, IMSIN, IMCOS, IMSINH and IMCOSH keep exact results where Excel shows the same kind of noise (`IMPOWER("-4",2)` is `16-3.92047505570758E-15i`) or different trailing digits near multiples of pi/2; IMCSC and IMCSCH differ by one unit in the 15th digit; IMARGUMENT returns 16–17 digits where Excel returns 15; the text of IM* and COMPLEX results differs for some magnitudes (Excel writes `COMPLEX(1E-10,1)` as `0.0000000001+i` but `COMPLEX(0.000000123456789012345,1)` as `1.23456789012345E-07+i`, and an integer past 15 digits rounded and zero-padded) |
|
||||
| MOD quotient limit | done: Excel 16.0 returns `#NUM!` when `ABS(number/divisor) >= 1.1259E12`; lower quotients retain the remainder |
|
||||
@@ -171,6 +172,7 @@ workbooks; results checked in as data, not Excel files) and fixing what it finds
|
||||
| 2026-10-14 | minor | MATCH, XMATCH, VLOOKUP, HLOOKUP, XLOOKUP and LOOKUP compare numbers exactly in every match and search mode, as Excel 365 does: `MATCH(0.1+0.2,{0.3},0)` is `#N/A` and 0.3 sorts below 0.30000000000000004 in approximate and binary search. `=`, SWITCH and the criteria functions (COUNTIF(S), SUMIF(S), AVERAGEIF(S), MAXIFS…) keep comparing at 15 significant digits, also as observed |
|
||||
| 2026-10-14 | minor | Analysis ToolPak value arguments (EOMONTH, WORKDAY, YEARFRAC, COUPDAYS, DISC, BIN2DEC, IM* and the rest, observed in Excel 365) give `#VALUE!` for a multi-cell reference instead of lifting it |
|
||||
| 2026-10-13 | minor | Clear reports changed stored cells sparsely, including those beyond the first million coordinates; dependent formulas and removed spills update, while clearing empty merges still unblocks spills (#1032) |
|
||||
| 2026-10-14 | minor | Set precision as displayed: results, spills and typed or reformatted numbers are stored as their format shows them when the option is on (#1343) |
|
||||
| 2026-10-14 | minor | Bounded references up to 1,048,576 cells (`D3:AZ400`) keep their full shape instead of stopping at the used range, so `SUMPRODUCT(D3:AZ400*B3:B400,(A3:A400=x)*(D1:AZ1=y))` broadcasts like Excel and `ROWS`, `COUNTBLANK` and `--(r="")` count the blanks; references that run to the edge of the sheet (`A:A`) still stop at the used range (#1010) |
|
||||
| 2026-10-12 | minor | USDOLLAR added as a Compatibility function (not on Microsoft's list, so the counts don't change); MIRR with no positive flow is -1, COUNTIF's bare `"<="` / `">="` skip empty strings, INDIRECT with `a1` = FALSE gives `#REF!` for A1-style text (#738) |
|
||||
| 2026-10-11 | minor | TEXT / number formats fixed against Excel-cached results: fraction literals and zero fractions, `0` denominators zero padded, `?` pads the thousands separator, booleans use the text section (226 mismatches → 0 in 352 TEXT cells) |
|
||||
|
||||
Reference in new issue
Block a user