Engineering functions

ERF

Close: 2 of 4 recorded answers differ in the last bits, worst 1 ULP

Everything else matches (4 workbook cells). Last-bit means a finite number within 16 ULP of Excel's. How we measure this · See the Rust code

Local names in 40 languages
LanguageName in Excel
ArabicERF
BulgarianERF
CzechERF
DanishFEJLFUNK
GermanERF
GreekERF
English (Australia)ERF
English (United Kingdom)ERF
English (United States)ERF
SpanishFUN.ERROR
EstonianERF
FinnishVIRHEFUNKTIO
FrenchERF
HebrewERF
CroatianERF
HungarianHIBAF
IndonesianERF
ItalianERF
JapaneseERF
KoreanERF
LithuanianERF
LatvianERF
NorwegianERF
DutchFOUTFUNCTIE
PolishFUNKCJA.BŁ
Portuguese (Brazil)ERF
Portuguese (Portugal)FUNCERRO
RomanianERF
RussianФОШ
SlovakERF
SlovenianERF
Serbian (Latin)ERF
SwedishFELF
ThaiERF
TurkishHATAİŞLEV işlevi
UkrainianERF
VietnameseERF
Chinese (Simplified)ERF
Chinese (Hong Kong)ERF
Chinese (Traditional)ERF

Names from Microsoft's support site.

What it does

ERF(lower_limit, [upper_limit])

ERF(lower_limit, [upper_limit]) returns the normalised integral of exp(-t*t) between the limits. With one argument it integrates from zero to that argument; with two it subtracts the lower primitive from the upper.

Try it

Input cells (optional)

Example: {"B2": 3, "B3": 4}. A1 holds the formula. Other cells need values before a formula can read them.

Enter a formula, then calculate.

Runs locally in your browser with OneCalc. Its answer may differ from Excel. Use English function names and commas between arguments.

=ERF(0.25) is about 0.276326390168237. =ERF(0.1,0.25) computes the integral over just that interval; reversing the two bounds negates it.

Quirks

Nonnumeric arguments give #VALUE!. The PRECISE name does not imply correctly rounded results on every input. The measured below-half stage and the unresolved upper stage need separate treatment. Subnormal inputs transferred to worksheet cells can be read back as zero, so the input route is part of a useful reproduction.

The recorded two-argument ERF wrapper reads left to right and rejects logicals: ERF(TRUE,#REF!) returns #VALUE!, while ERF(#REF!,TRUE) returns #REF!. DELTA and GESTEP have a different recorded read order.

DELTA and GESTEP read their second argument first

When both arguments of DELTA or GESTEP are bad, the error comes from the second one: DELTA(TRUE,#REF!) is #REF! and DELTA(#REF!,TRUE) is #VALUE!. With two errors, DELTA gives the second. ERF reads left to right: ERF(TRUE,#REF!) is #VALUE! and ERF(#REF!,TRUE) is #REF!. A logical is rejected in either position of these functions, whether typed or held in a cell: DELTA(TRUE,0) and DELTA(2,TRUE) are #VALUE!, and DELTA(B1,0) with TRUE in B1 is #VALUE!, while an empty B1 reads as 0 and gives 1.

FormulaExcelMathematical value
=DELTA(TRUE,#REF!)
Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA
Inputs and reference value

Typed formula.

#REF!—
=DELTA(#REF!,TRUE)
Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA
Inputs and reference value

Typed formula.

#VALUE!—
=GESTEP(TRUE,#REF!)
Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA
Inputs and reference value

Typed formula.

#REF!—
=GESTEP(#REF!,TRUE)
Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA
Inputs and reference value

Typed formula.

#VALUE!—
=ERF(TRUE,#REF!)
Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA
Inputs and reference value

Typed formula.

#VALUE!—
=ERF(#REF!,TRUE)
Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA
Inputs and reference value

Typed formula.

#REF!—
DELTA(A1, A2)
Excel 16.0.20527.20088, Windows, bitness and CPU not recorded in this reading file
Inputs and reference value

Number supplied through a cell.

number1: #N/A

number2: #REF!

#REF!—
=DELTA(B1,0)
Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA
Inputs and reference value

Number supplied through a cell.

B1: TRUE

#VALUE!—
=DELTA(B1,0)
Excel 16.0.20527.20088 Current Channel, Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA
Inputs and reference value

Number supplied through a cell.

B1: (empty cell)

1
0x3ff0000000000000
—

Inputs, build details and evidence

Below 0.5, ERF is a stored (4, 5) rational from a table not yet identified

With RN(v) meaning v rounded to 64 bits on the x87 unit and then stored to binary64, ERF.PRECISE for |x| < 0.5 is x*N(t)/D(t) with t = RN(x*x), p = RN(x*N), y = RN(p/D), and N and D Horner sums in t in which every product and every sum is RN. N has degree 4 and D degree 5, and the coefficients read off Excel's answers, order 0 upward, are N: 0x3ff1df5e70c7956b, 0x3fc201d8627a7d2c, 0x3fa6f289d165b303, 0x3f5d93a5813e372c, 0x3f2932767df264b2; D: 0x3fefada15778ece6, 0x3fdd191aca8d2499, 0x3fb79f85ba68803e, 0x3f856de5da86af12, 0x3f4609751b5b6488, 0x3ef4f20a473a5ab0. The rational stops at 0.5 itself. It equals erf to a flat 9E-17 up to 0.5, and its error climbs at once beyond, so 0.5 is its design interval and not Cody's 0.46875. No published table has been matched: Cody's 1969 rational is refuted by its linear terms, and Cephes has the same shape with different ratios. Evidence record EV-DIST-0026, which predates this note, attributes ERF.PRECISE and ERFC.PRECISE to the a < 1 branches of the NSWC GRATIO routine and says no coefficient table exists; below 0.5 this note replaces that attribution. Because every step rounds, answers need not be correctly rounded: of the 654 recorded rows of build 20131 in [0.25, 0.5), 400 differ from the correctly rounded erf, by up to 3 units, and small arguments can be 1 unit high, as below. ERFC and ERFC.PRECISE below 0.5 are 1 less this value, and GAUSS at tiny arguments takes half of it at its stored z/sqrt(2).

Explanation (inferred): That the legacy ERF(x) shares this body is inferred: ERF.PRECISE, ERFC and ERFC.PRECISE rows were scored in full, and for ERF itself the record holds only nine non-zero single-argument inputs below 0.5 (build 19929), all equal to the rational.

FormulaExcelMathematical value
ERF.PRECISE(0.4524739583333333)
Excel 16.0 build 20131, platform and bitness not recorded, AMD Ryzen 7 4800H
Inputs and reference value

Number supplied through a cell.

x: 0.4524739583333333
0x3fdcf55555555555

mpmath erf at 800 bits from the binary64 input, correctly rounded.

0.4777590107351978
0x3fde939a879e86f6
0.4777590107351976
0x3fde939a879e86f3
ERF.PRECISE(9.094947017729282e-13)
Excel 16.0 build 20131, platform and bitness not recorded, AMD Ryzen 7 4800H
Inputs and reference value

Number supplied through a cell.

x: 9.094947017729282e-13
0x3d70000000000000

mpmath erf at 800 bits from the binary64 input, correctly rounded.

1.0262548740643186e-12
0x3d720dd750429b6e
1.0262548740643184e-12
0x3d720dd750429b6d
ERF.PRECISE(9.999999999999998e-11)
Excel 16.0 build 20131, platform and bitness not recorded, AMD Ryzen 7 4800H
Inputs and reference value

Number supplied through a cell.

x: 9.999999999999998e-11
0x3ddb7cdfd9d7bdb9

mpmath erf at 800 bits from the binary64 input, correctly rounded.

1.1283791670955125e-10
0x3ddf044332d68160
1.1283791670955123e-10
0x3ddf044332d6815f

Inputs, build details and evidence

How to implement

For normal abs(x)<0.5, use R(op)=RN53(RN64(op)): round each operation to a 64-bit significand, then store to binary64. Decode the following hexadecimal strings as binary64 bit patterns, not integers converted to floating-point values.

PowerNumerator coefficientDenominator coefficient
03ff1df5e70c7956b3fefada15778ece6
13fc201d8627a7d2c3fdd191aca8d2499
23fa6f289d165b3033fb79f85ba68803e
33f5d93a5813e372c3f856de5da86af12
43f2932767df264b23f4609751b5b6488
5—3ef4f20a473a5ab0
  1. Store t=R(x*x).
  2. Evaluate each polynomial by Horner, beginning with its highest-power coefficient. Every step is v=R(R(v*t)+coefficient). Keep the multiplication store separate from the addition store; do not use FMA.
  3. Store p=R(x*N) and return R(p/D).

Worked x=0.25: t=0.0625; the staged coefficient evaluation gives N=1.126001525484713, D=1.018724202200851, p=0.2815003813711783, and result 0.276326390168237 (0x3fd1af54e232d60a). These are outputs of the stated reconstruction, with all input coefficients retained above.

The degrees and stores are supported by discriminating readings. The final bits of several higher-order coefficients remain open: the fixed c14 model matched 59,982 of a fresh 60,000-row holdout. Do not extrapolate this ratio above abs(x)=0.5. For larger magnitudes the current code uses the signed stored complement copysign(R(1-upper_ERFC(abs(x))),x). At exactly plus or minus 0.5 it instead retains its runtime ERF fallback. The fixed ratio and the mathematical value agree in bits at the positive half point, so that single recorded answer does not identify which private branch owns it. Zero and nonnormal inputs also retain the fallback and their separate transfer/publication rules. The upper ERFC exponential stage is measured, but its remaining rational factor is a stand-in. No published Handbook suite establishes a whole-domain equality claim.

For the two-limit form the current kernel subtracts the two separately evaluated primitives in binary64. Nearly equal endpoints can lose relative accuracy; that wrapper is a separate obligation from the rational body.

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.

ERF · 6 lines · calc-func/src/catalogue/distributions.rs on GitHub
90 erf "ERF" (1, 2) [V "lower_limit", V "upper_limit"] |s, a, sv| {
    reject_logical(&a[0])?;
    let lower = num(s, a, 0)?;
    let upper = if a.len() > 1 { Some(super::kit::num_without_logical(s, a, 1)?) } else { None };
    out(s, sd::erf_kernel(lower, upper))
}
erf_interval · 3 lines · calc-func/src/ported/special_dist_family.rs on GitHub
fn erf_interval(lower: f64, upper: f64) -> f64 {
    erf_approx(upper) - erf_approx(lower)
}
erf_kernel · 9 lines · calc-func/src/ported/special_dist_family.rs on GitHub
pub fn erf_kernel(lower: f64, upper: Option<f64>) -> Result<f64, WorksheetErrorCode> {
    if !lower.is_finite() || upper.is_some_and(|v| !v.is_finite()) {
        return Err(WorksheetErrorCode::Num);
    }
    Ok(match upper {
        Some(upper) => erf_interval(lower, upper),
        None => erf_approx(lower),
    })
}

Kernels shared with other functions

Argument and result plumbing

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 buildPlatform and CPUCaptured inputs
19929Windows, bitness not recorded, CPU not recorded42

The record contains no same-input comparison between these environments. Reading different inputs on different builds does not establish either a version change or cross-build agreement.

Recorded environments and comparison details.

Retained controls from the indexed captures:

Build and recorded CPUCaptured call or argumentsExcel result
19929, CPU not recorded=ERF(0)0.0 (0x0000000000000000)

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.20527.20088

Windows 64-bit (NT 10.0.26200), x86-64, AMD Ryzen 7 4800H, en-ZA

=ERF(TRUE,#REF!) returned #VALUE!. =ERF(#REF!,TRUE) returned #REF!. Inputs were supplied through formula literals. These are controls from this environment, not a same-input comparison with another build.

Observed formulas and results
  • =ERF(TRUE,#REF!) → #VALUE! (formula-literal)
  • =ERF(#REF!,TRUE) → #REF! (formula-literal)

Excel 16.0 build 19929

Windows, bitness not recorded, CPU not recorded

42 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 =ERF(0) returned 0.0 (0x0000000000000000). The selected archive row does not record its input plumbing; no input route is inferred.

Observed formulas and results
  • =ERF(0) → 0.0
    0x0000000000000000 (not-recorded)

Alternatives

ERFC computes the complementary tail directly. NORM.S.DIST provides a standard-normal CDF with a different argument transformation.

Named variants

No named variants are recorded yet.

Suggest a correction or contribute an implementation · For agents