erf
MathComputes the Gauss error function erf(x) using West's rational approximation.
Gas
685
Max abs. error
7.4e-15
Signature
function erf(int256 x) internal pure returns (int256 y)Parameters
| Name | Type | Description |
|---|---|---|
| x | int256 | Signed input in 18-decimal fixed-point format (1e18 = 1.0). |
Returns
| Name | Type | Description |
|---|---|---|
| y | int256 | erf(x) in 18-decimal fixed-point format, in range [-1e18, 1e18]. |
Behavior
- Antisymmetric:
erf(−x) = −erf(x). Handled internally — pass any signedint256. - Saturates gracefully (no revert): returns
±1e18for|x| ≥ 11.63, where the true value is within1e-58of±1. - Reuses the internal
expPositivefor the gaussian factor — no separate transcendental machinery. - Pure assembly final block; no external calls or storage.
How it works
The error function erf(x) = (2/√π) · ∫₀ˣ e^(−t²) dt has no closed form, so DeFiMath uses West's rational approximation — the same machinery stdNormCDF uses, with a single substitution to map between domains. The trick is the change of variable t = x · √2, which expresses erf in the gaussian-integral form West's paper was designed for:
erf(x) = 1 − 2 · R(t) · e^(−t²/2), where R(t) = num(t)/denom(t)
R(t) is a ratio of seventh-degree polynomials. Both numerator and denominator are evaluated in nested form — powers up to t⁴ precomputed once, then a single multiply-add pass — so the whole rational reduces to a handful of multiplications. The exponential e^(−t²/2) reuses our internal expPositive, which keeps the gas budget low and the error bound consistent with the rest of the library.
For x < 0 we exploit erf(−x) = −erf(x): compute the positive branch and negate. For |x| ≥ 11.63 the true value is within 1e-58 of ±1 — far below 1e-18 precision — so the function saturates to ±1e18 and skips the kernel entirely.
The hot path closes with a five-instruction assembly block that fuses the reciprocal, multiply, divide, subtract-from-half, and double into a tight sequence. Result: ~685 gas at max abs. error 7.4e-15.
Example
import "defimath-lib/contracts/math/Math.sol";
int256 x = 1e18; // x = 1.0
int256 y = DeFiMath.erf(x); // y ≈ 0.84270079e18