由於工作中需要將Excel中的此兩種函數轉換成java函數,從而計算內部評級的資本占用率和資本占用金額。經過多方查閱資料和整理,總結出如下兩個轉換方法
標准正態分布累計函數NORMSDIST:
public static double NormSDist(double z) { // this guards against overflow if (z > 6) return 1; if (z < -6) return 0; double gamma = 0.231641900, a1 = 0.319381530, a2 = -0.356563782, a3 = 1.781477973, a4 = -1.821255978, a5 = 1.330274429; double x = Math.abs(z); double t = 1 / (1 + gamma * x); double n = 1 - (1 / (Math.sqrt(2 * Math.PI)) * Math.exp(-z * z / 2)) * (a1 * t + a2 * Math.pow(t, 2) + a3 * Math.pow(t, 3) + a4 * Math.pow(t, 4) + a5 * Math.pow(t, 5)); if (z < 0) return 1.0 - n; return n; }
標准正態分布累計反函數NORMSINV:
public static double normsinv(double p) { double LOW = 0.02425; double HIGH = 0.97575; double a[] = { -3.969683028665376e+01, 2.209460984245205e+02, -2.759285104469687e+02, 1.383577518672690e+02, -3.066479806614716e+01, 2.506628277459239e+00 }; double b[] = { -5.447609879822406e+01, 1.615858368580409e+02, -1.556989798598866e+02, 6.680131188771972e+01, -1.328068155288572e+01 }; double c[] = { -7.784894002430293e-03, -3.223964580411365e-01, -2.400758277161838e+00, -2.549732539343734e+00, 4.374664141464968e+00, 2.938163982698783e+00 }; double d[] = { 7.784695709041462e-03, 3.224671290700398e-01, 2.445134137142996e+00, 3.754408661907416e+00 }; double q, r; if (p < LOW) { q = Math.sqrt(-2 * Math.log(p)); return (((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) / ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1); } else if (p > HIGH) { q = Math.sqrt(-2 * Math.log(1 - p)); return -(((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) / ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1); } else { q = p - 0.5; r = q * q; return (((((a[0] * r + a[1]) * r + a[2]) * r + a[3]) * r + a[4]) * r + a[5]) * q / (((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4]) * r + 1); } }
不足之處,敬請指出