MROUND(number, multiple) selects a nearest multiple, with mathematical halves away from zero. Both nonzero inputs must have the same sign.
Try it
=MROUND(14,4) returns 16. =MROUND(-14,-4) returns -16. For decimal multiples, Microsoft documents differing midpoint directions: MROUND(6.05,0.1) gives 6, while MROUND(7.05,0.1) gives 7.1.
Quirks
Opposite signs give #NUM!; the current implementation returns zero for a zero multiple. A decimal multiple is already a binary64 approximation before rounding begins. The recorded decision admits a small tolerance below one half, rather than comparing exact decimal distances.
MROUND counts a quotient within 5E-15 below a half up
MROUND(n,m) forms q = n/m on the x87 unit and stores it to binary64, counts floor(q), adds 1 when 0.5 - frac(q) <= 5E-15, and returns count*m from the x87 unit. A number just below a half therefore rounds up though it is nearer the lower multiple: 0.499999999999995 with multiple 1 gives 1, and the next binary64 below it gives 0. MROUND(6.05,0.1) stays 6, because its quotient 60.49999999999999 lies 7.1E-15 below the half.
Explanation (inferred): The window is measured between two neighbouring values; that the constant is the decimal 5E-15 is inferred, as the decimal in that window.
Formula
Excel
Mathematical value
MROUND(0.499999999999995, 1) Excel 16.0 build 20430, Windows 64-bit, CPU not recorded in this captureInputs and reference value
Number supplied through a cell.
number: 0.499999999999995 0x3fdfffffffffffa6
multiple: 1 0x3ff0000000000000
The number is nearer to 0 than to 1.
1 0x3ff0000000000000
0 0x0000000000000000
MROUND(0.49999999999999495, 1) Excel 16.0 build 20430, Windows 64-bit, CPU not recorded in this captureInputs and reference value
Number supplied through a cell.
number: 0.49999999999999495 0x3fdfffffffffffa5
multiple: 1 0x3ff0000000000000
0 0x0000000000000000
—
MROUND(0.49999999999999994, 1) Excel 16.0 build 20430, Windows 64-bit, CPU not recorded in this captureInputs and reference value
After coercion and sign checks, compute q=R(number/multiple), where R is the stored 64-bit-significand operation described for variance. Let c=floor(q) and f=q-c. Increment c when 0.5-f<=5e-15. Return R(c*multiple).
Worked: 14/4=3.5; c=3, f=0.5, so increment to four and multiply by four to obtain sixteen. The same positive quotient with two negative arguments produces a negative multiple. Preserve the division store and final product store, and use the binary64 constant 5e-15 rather than a decimal-string comparison. The adjacent-half probes distinguish the tolerance on the measured inputs. The cited bank contains 50,782 matching rows; no Handbook suite has been published.
Rust code
Show the CalcFunc source of this function
Quoted from the public repository DnaCalc/DnaCalc, crates calc-func and calc-fml, at commit 9e1884369a67. Comments are the source's own. A kernel shared with other functions appears once, on its module page.
/// The multiple MROUND chooses for `number` and `multiple`, both non-zero and of one sign: the/// count of multiples is the integer part of their quotient, a division at an arithmetic site,/// plus one when the quotient's fraction is a half or within [`MROUND_HALF_TOLERANCE`] below it;/// the result is the count times the multiple, a product at an arithmetic site (dc-j9k). So/// MROUND(6.05,0.1) is 6, its quotient 60.49999999999999 lying 7.1E-15 below the half, while/// MROUND(23.499999999999996,1) is 24 and MROUND(-0.04999999999999977,-0.1) is -0.1, as Excel/// 16.0.20430 gives them (the OxFunc-Evidence bank's half-boundary and fraction-cutoff runs). A/// quotient beyond binary64's range is #NUM!.fnnearest_multiple(site: &Site<'_>, number: f64, multiple: f64) -> Step<f64> {
// Positive, since the signs agree.let quotient = site.divide(number, multiple)?;
if quotient.is_infinite() {
returnErr(Exit::Error(WorksheetErrorCode::Num));
}
let whole = decimal::floor(quotient);
// Exact: the fraction of a binary64, and its distance below a half when it is near one.let below_half = 0.5 - (quotient - whole);
let count = if below_half <= MROUND_HALF_TOLERANCE {
whole + 1.0
} else {
whole
};
site.multiply(count, multiple)
}
No implementation has been published with a Handbook test suite for this function.
Version differences
The recorded environments below distinguish a reading from a same-input comparison. Counts describe captured inputs in each environment; overlapping captures and comparisons are not totals of unique worksheet calls.
Excel 16.0 build
Platform and CPU
Captured inputs
19929
Windows, bitness not recorded, CPU not recorded
108
20430
Windows, 64-bit, AMD Ryzen 7 4800H with Radeon Graphics
1,999
20430
Windows, 64-bit, CPU not recorded
48,783
XC-MROUND-001: build 19929 versus build 20430; 3 same-input pairs, 0 differing answers. Compared axes: excel-build. Numeric answers were compared by their recorded binary64 bits; other answers by typed value.
Agreement on these compared inputs does not establish agreement on unmeasured inputs.
These are earlier recorded answers, not new Excel runs or an additional cross-build comparison. The function JSON retains each source locator, exact argument bits where available, and input-route status. Call notation does not imply that captured binary64 values were entered as decimal formula literals.
Excel 16.0 build 20430
Windows 64-bit, CPU not recorded in this capture
MROUND(0.499999999999995, 1) returned 1 (0x3ff0000000000000). MROUND(0.49999999999999495, 1) returned 0 (0x0000000000000000). 1 further recorded control is attached. Inputs were supplied through cells using Value2. These are controls from this environment, not a same-input comparison with another build.
108 captured inputs are indexed for this environment. Capture dates are not recorded. This is a reading count, not a comparison with another build. Retained control =MROUND(0,0.25000000000000000) returned 0.0 (0x0000000000000000). The selected archive row does not record its input plumbing; no input route is inferred.
Windows, 64-bit, AMD Ryzen 7 4800H with Radeon Graphics
1,999 captured inputs are indexed for this environment. Capture dates: 2026-09-25 to 2026-09-25. This is a reading count, not a comparison with another build. Retained control MROUND(45.5,7) returned 49 (0x4048800000000000). The selected archive row does not record its input plumbing; no input route is inferred.
48,783 captured inputs are indexed for this environment. Capture dates: 2026-09-29 to 2026-09-29. This is a reading count, not a comparison with another build. Retained control MROUND(0.5,1) returned 1 (0x3ff0000000000000). The capture specifies exact-double bulk Value2 cell input.