← All guides

DOLLARDE and DOLLARFR agree on every price — and disagree on every error

US bond and note prices are quoted in fractions, not decimals. A price of 1.02 in sixteenths does not mean one dollar and two cents; it means one and two-sixteenths, which is 1.125. DOLLARDE converts that notation into a decimal you can do arithmetic with, and DOLLARFR converts it back for display. Any sheet that reads a price feed and then multiplies by a face value has one of each somewhere in the chain.

We executed the whole corpus for both functions in LibreOffice Calc 25.8.7.3 and Google Sheets. The result splits cleanly in two: every conversion agrees, and every error disagrees. All eight valid cases — including Microsoft’s own documented examples, a negative price, a round trip, and the documented truncation of a non-integer fraction — returned the documented value in both engines. All four error cases returned #VALUE! in LibreOffice where Microsoft documents #DIV/0! or #NUM!, and Google Sheets returned the documented code on all four.

The surprise

The arithmetic is not the risk here — it is exact and it travels. The risk is that a price sheet built around DOLLARDE and DOLLARFR almost always has guard logic wrapped around it, because a fraction denominator arriving as zero or negative is a real thing that happens when a feed hiccups or a lookup misses. That guard is what breaks. A branch keyed on #DIV/0! or on ERROR.TYPE(...)=6 stops firing in LibreOffice, because both conditions arrive as #VALUE! instead. All four LibreOffice builds we tested (24.2.0.3, 24.8.7.2, 25.2.0.3 and 25.8.7.3) behave identically.

Executed: all twelve cases

The Excel column is Microsoft’s documented behaviour as recorded in our test corpus — it is the yardstick, and we do not run Excel. The Google Sheets column is executed output from the dated Drive-import run of 2026-08-31. The LibreOffice column is Calc 25.8.7.3, and every row returned the identical result in 24.2.0.3, 24.8.7.2 and 25.2.0.3.

FormulaWhat it asksExcel (documented)Google Sheets (executed 2026-08-31)LibreOffice Calc 25.8.7.3 (executed)
=ROUND(DOLLARDE(1.02,16),7)1 and 2/16 as a decimal1.1251.1251.125
=ROUND(DOLLARDE(1.1,32),7)1 and 10/32 as a decimal1.31251.31251.3125
=ROUND(DOLLARDE(1.02,16.9),7)a non-integer fraction argument1.1251.1251.125
=ROUND(DOLLARDE(-1.02,16),7)a negative price-1.125-1.125-1.125
=DOLLARDE(1.02,0)fraction of zero#DIV/0!#DIV/0!#VALUE!
=DOLLARDE(1.02,-4)a negative fraction#NUM!#NUM!#VALUE!
=ROUND(DOLLARFR(1.125,16),7)1.125 back into sixteenths1.021.021.02
=ROUND(DOLLARFR(1.125,32),7)1.125 back into thirty-seconds1.041.041.04
=ROUND(DOLLARFR(DOLLARDE(1.02,16),16),7)a full round trip1.021.021.02
=ROUND(DOLLARFR(1.125,16.9),7)a non-integer fraction argument1.021.021.02
=DOLLARFR(1.125,0)fraction of zero#DIV/0!#DIV/0!#VALUE!
=DOLLARFR(1.125,-4)a negative fraction#NUM!#NUM!#VALUE!

The fraction argument is truncated, not rounded

Microsoft states it in one line on both pages: “If fraction is not an integer, it is truncated.” That is a rule worth having an executed case for, because the two plausible behaviours give different money. We ran =DOLLARDE(1.02,16.9), which under truncation is =DOLLARDE(1.02,16) and therefore 1.125, and under rounding would be =DOLLARDE(1.02,17) and something else entirely. Both engines returned 1.125. The paired DOLLARFR case returned 1.02, likewise the truncated answer.

This matters more than it looks. A fraction denominator is rarely typed as a literal in a real sheet — it usually comes out of a lookup, a division, or a cell someone formatted to zero decimal places while the underlying value still carries a fraction. If that cell holds 15.999999 because of a floating-point round trip, truncation makes it 15 and every price in the column converts against the wrong denominator, silently and consistently. The behaviour is portable across both engines we executed, so migration does not introduce this — but if you are already auditing these formulas, the denominator is the argument to look at.

Microsoft documents the #DIV/0! condition two different ways

The two pages describe the same failure with different boundaries, and this is a documentation asymmetry rather than an engine one.

DOLLARDE: “If fraction is greater than or equal to 0 and less than 1, DOLLARDE returns the #DIV/0! error value.” That is a band: 0 ≤ fraction < 1.

DOLLARFR: “If fraction is 0, DOLLARFR returns the #DIV/0! error value.” That is a single point.

In practice the two are equivalent, because the truncation rule fires first: any fraction in [0, 1) truncates to 0, so DOLLARFR’s narrower wording reaches the same set of inputs by a different route. The wider DOLLARDE wording is arguably the clearer description of what both functions do. But they are published differently, and if you are reading the documentation to decide what a guard should catch, you will get a different answer depending on which of the two pages you happen to open.

Our corpus probes only the endpoints of that band — fraction = 0 and fraction = -4. We have no executed case for an interior value such as fraction = 0.5, so which of the two documented readings each engine actually implements there is untested here and we are not going to infer it from the truncation rule.

The error rows, and what they break

Four rows, four #VALUE!s in LibreOffice, and two distinct documented codes underneath them. That is worth separating out, because it means neither of the two obvious targeted guards survives:

A #DIV/0!-specific check misses. =DOLLARDE(price,0) and =DOLLARFR(price,0) are documented #DIV/0!, are #DIV/0! in Sheets, and are #VALUE! in LibreOffice. Anything written as =IF(ERROR.TYPE(x)=2,"no denominator",x) stops firing.

A #NUM!-specific check misses too. The negative-fraction rows are documented #NUM!ERROR.TYPE code 6 — and arrive as #VALUE!, code 3.

IFERROR and ISERROR are unaffected, because they catch every code. If your price sheet wraps these calls in IFERROR and shows a dash, nothing on this page will change its behaviour.

The trap is specifically the sheet that wants to distinguish “the feed sent no denominator” from “the denominator is nonsense” and encodes that distinction in error codes. Those two conditions are genuinely different operationally — one is a missing value, one is bad data — and Excel and Sheets let you tell them apart while LibreOffice does not.

These four rows are part of a much larger pattern: across our corpus, 41 executed cases in 29 functions return #VALUE! in LibreOffice where Microsoft documents a different error code. The full list, the counts, and the exceptions that run the other way are in every error code LibreOffice reports as #VALUE!.

Migrating a price sheet

The prices themselves are safe. This is the good news and it is worth stating plainly: every conversion in the table above matched to seven decimal places in both executed engines, including the round trip. DOLLARDE and DOLLARFR are not functions whose numbers you need to re-verify after a migration.

Audit the guards, not the conversions. Grep for ERROR.TYPE, ISNA(, IFNA( and ISERR( in the neighbourhood of every DOLLARDE and DOLLARFR. Those are the formulas whose meaning changes.

Validate the denominator before the call. The portable version of the guard tests the input rather than the wreckage: something in the shape of =IF(NOT(ISNUMBER(f)),"bad feed",IF(INT(f)<1,"no denominator",DOLLARDE(p,f))) gives the same answer in every engine, and it also catches the truncation hazard in the same breath, since it tests INT(f) rather than f. That is a construction we are describing from the documented and executed behaviour above, not a case we ran — treat it as a suggested shape, not as a measured result.

Watch out for the round trip in reporting. A common pattern is to convert to decimal for arithmetic and back to fractional for display. Our round-trip case matched everywhere on a value with an exact binary representation (0.125). Prices that are not exact sixteenths or thirty-seconds — anything with a real floating-point remainder — are not covered by our corpus, so if your sheet round-trips computed averages or interpolated prices rather than quoted ones, that is worth checking directly.

Honest limits

The Excel column throughout, including both wordings of the #DIV/0! condition, the truncation rule and the ERROR.TYPE code numbers, is Microsoft’s documented behaviour as recorded in our test corpus. We do not run Excel, and no value in that column is a measurement.

The Google Sheets column is executed output from a dated run, because Sheets has no version number to pin: a formula-only .xlsx carrying no cached results goes to Google Drive, is recalculated by Google’s engine, and comes back as .xlsx for readback, with a deterministic =1111+2222 canary in every sheet proving the recalculation happened. These twelve cases ran on 2026-08-31.

The LibreOffice column is executed output from Calc 25.8.7.3; all twelve cases returned the identical results in 24.2.0.3, 24.8.7.2 and 25.2.0.3. Those four builds are the only ones we tested.

Scope. Twelve cases is the entire DOLLARDE/DOLLARFR corpus, and it is small. Untested here: fractions strictly between 0 and 1, fraction denominators that are not powers of two, text or logical arguments to either function, very large fractions, and prices whose fractional part exceeds the denominator (a quote like 1.20 in sixteenths, which asks for twenty sixteenths). See our methodology for how recalculation is proven rather than assumed, and the function pages for DOLLARDE and DOLLARFR for the per-engine support matrices.

Check before you migrate