stdNormCDF
MathComputes the standard normal cumulative distribution function Φ(x) — the probability that a standard normal random variable is ≤ x.
Gas
731
Max abs. error
4.7e-15
Signature
function stdNormCDF(int256 x) internal pure returns (uint256 y)Parameters
| Name | Type | Description |
|---|---|---|
| x | int256 | Signed input in 18-decimal fixed-point format (1e18 = 1.0). |
Returns
| Name | Type | Description |
|---|---|---|
| y | uint256 | Φ(x) in 18-decimal fixed-point format, in range [0, 1e18]. |
Behavior
- Symmetric:
Φ(−x) = 1 − Φ(x). Handled internally — pass any signedint256. - Saturates gracefully (no revert): returns
1e18forx ≥ 16.447and0forx ≤ −16.447, where the true value is within1e-60of the bound. - Built on the same West's approximation as erf — calling
stdNormCDFis the same kernel with one substitution. - Pure assembly hot path; no external calls or storage.
How it works
The standard normal CDF and the error function are the same beast in different coordinates. The textbook identity
Φ(x) = (1 + erf(x / √2)) / 2
is how DeFiMath computes Φ — substitute u = x · (1/√2) (the constant 0.7071067811865475…) and pass it through the same West's rational approximation that powers erf. So stdNormCDF and erf share the rational kernel — there's no second numerical method to maintain.
Internally we call erfPositiveHalf(|u|), which returns erf(|u|) / 2 directly. That saves one shift and one add per call. For x ≥ 0 the result is 0.5 + erfPositiveHalf(u); for x < 0 we exploit Φ(−x) = 1 − Φ(x) and return 0.5 − erfPositiveHalf(|u|). Either branch costs the same.
Saturation handles the tails: at x = ±16.447 the true Φ is within 1e-60 of 0 or 1, well below 1e-18 representational precision, so the function short-circuits to the boundary and skips the kernel. Net cost on the hot path: ~731 gas including the divide-by-√2 substitution and the West kernel — the cheapest on-chain Φ we've measured by a wide margin.
Example
import "defimath-lib/contracts/math/Math.sol";
int256 x = 1.96e18; // the canonical 95% confidence cutoff
uint256 y = DeFiMath.stdNormCDF(x); // y ≈ 0.97500210e18