scratch lenet(8): C语言实现 exp(x) 的计算

1. 目的

LeNet-5 中的 squashing function 中,使用到了 hyperbolic tangent(双曲正切三角函数)
f ( a ) = A tanh ⁡ ( S a ) f(a) = A \tanh(Sa) f(a)=Atanh(Sa)
而 tanh 展开式出现了 exp ⁡ ( x ) \exp(x) exp(x):
tanh ⁡ ( x ) = e x − e − x e x + e − x \tanh(x) = \frac{e^x-e^{-x}}{e^x+e^{-x}} tanh(x)=ex+exexex

因此需要先计算 exp ⁡ ( x ) \exp(x) exp(x).

2. exp ⁡ ( x ) \exp(x) exp(x) 定义式

也叫做泰勒展开:
exp ⁡ ( x ) = ∑ 0 ∞ x n n ! \exp(x) = \sum_{0}^{\infty} \frac{x^n}{n!} exp(x)=0n!xn

也可以显式的写出前面几项:
exp ⁡ ( x ) = 1 + x + x 2 2 ! + x 3 3 ! + . . . + x n n ! \exp(x) = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + ... + \frac{x^n}{n!} exp(x)=1+x+2!x2+3!x3+...+n!xn

显然这是一个无限次累加的过程,具体实现时应当在一定迭代次数后停止,我选择的终止条件是 eps 小于 1e-5:

static double m_fabs(double n)
{
    return n >= 0.0 ? n : -n;
}

double m_exp(double x)
{
    double res = 1;
    double eps = 1e-5;
    double up = 1;
    double down = 1;
    for (int i = 1; ;i++)
    {
        up *= x;
        down *= i;
        double delta = up / down;
        res += delta;
        if (m_fabs(delta) < eps)
            break;
    }
    return res;
}

3. exp ⁡ ( x ) \exp(x) exp(x) 的快速计算

3.1 用极限公式近似

博客1 则使用极限进行近似:
e x = lim ⁡ n − > + ∞ ( 1 + x n ) n e^x = \lim_{n->+\infty}(1 + \frac{x}{n})^n ex=n>+lim(1+nx)n

据说取 n = 256 n=256 n=256 时可以得到不错的效果, 对应的实现为:(来自博客2 )

inline double exp1(float x)
{
    x = 1.0 + x / 256.0;
    x *= x; x *= x; x *= x; x *= x;
    x *= x; x *= x; x *= x; x *= x;
    return x;
}

n = 1024 n=1024 n=1024 展开,对应的实现为

inline double exp2(double x)
{
    x = 1.0 + x / 1024;
    x *= x; x *= x; x *= x; x *= x;
    x *= x; x *= x; x *= x; x *= x;
    x *= x; x *= x;
    return x;
}

3.2 转为 2 x ln ⁡ 2 2^{\frac{x}{\ln 2}} 2ln2x近似

StackOverFlow 上的一个问答3 给出了另一种近似思路: 转换 e x e^x ex 2 x ln ⁡ 2 2^{\frac{x}{\ln 2}} 2ln2x, 然后用 2 的幂次做快速计算。原理:
2 x ln ⁡ 2 = ( 2 1 ln ⁡ 2 ) x = ( 2 log ⁡ 2 e ) x = e x 2^{\frac{x}{\ln 2}} = (2^\frac{1}{\ln 2}) ^ x = (2 ^ {\log_{2} e})^x = e^x 2ln2x=(2ln21)x=(2log2e)x=ex

具体计算,则是把上述公式倒过来用:
e x = 2 x ln ⁡ 2 e^x = 2^{\frac{x}{\ln 2}} ex=2ln2x

而对于 f ( y ) = 2 y f(y) = 2^y f(y)=2y 的计算, 可以结合 IEEE-754 浮点数的二进制表示, 进行近似和加速, 例如参考4 给出的实现:

inline double fast_exp(double y)
{
    double d;
    *(reinterpret_cast<int*>(&d) + 0) = 0;
    *(reinterpret_cast<int*>(&d) + 1) = static_cast<int>(1512775 * y + 1072632447);
    return d;
}

C标准库中:

  • exp2f(x) 表示 2 x 2^x 2x.
  • logf(x) 表示 ln ⁡ ( x ) \ln(x) ln(x).

3.3 查表计算 exp ⁡ ( x ) \exp(x) exp(x)

在前一小节用 e x = 2 x ln ⁡ 2 e^x = 2^{\frac{x}{\ln 2}} ex=2ln2x 展开后, 计算 2 y 2^y 2y 的做法其实有多种, fast_exp() 函数里用到的公式是结合 IEEE-754 标准的二进制格式做的 hack 式实现, 有时候精度损失过大,例如计算 exp ⁡ ( 40 ) \exp(40) exp(40). 计算 2 y 2^y 2y 的过程可以考虑用多项式近似, 近似的过程中可以使用查表方式来加速, 计算多项式的过程用了 Horner’s method (其实就是秦九韶公式,高中课本提到过):
a 0 + a 1 x + a 2 x 2 + a 3 x 3 + . . . + a n x n = a 0 + x ( a 1 + x ( a 2 + x ( a 3 + . . . + x ( a n − 1 + x a n ) ) ) ) a_0 + a_1 x + a_2 x^2 + a_3 x^3 + ... + a_n x^n = a_0 + x(a_1 + x(a_2 + x(a_3 + ... + x(a_{n-1} + x a_n)))) a0+a1x+a2x2+a3x3+...+anxn=a0+x(a1+x(a2+x(a3+...+x(an1+xan))))

github 仓库 Logarithmic and Exponential Function Approximation 5 给出了一份具体的实现,它假定了 exp ⁡ ( x ) \exp(x) exp(x) x ∈ [ − 710 , 710 ] x \in [-710, 710] x[710,710] 的数据范围, 因此建立的表格是 1420 个元素, 对应的核心代码:


// Generated with:
// >>> from math import exp
// >>> [exp(i) for i in range(-710, 710)]
double EXP_TABLE[1420] = {
    ...
};

double __attribute__((noinline)) fast_exp(double x) {
    double integer = trunc(x);
    // X is now the fractional part of the number.
    x = x - integer;

    // Use a 4-part polynomial to approximate exp(x);
    double c[] = { 0.28033708, 0.425302, 1.01273643, 1.00020947 };

    // Use Horner's method to evaluate the polynomial.
    double val = c[3] + x * (c[2] + x * (c[1] + x * (c[0])));
    return val * EXP_TABLE[(unsigned)integer + 710];
}

4. 其他

参考6 是论文 A Fast, Compact Approximation of the Exponential Function 的主页。

参考7 是网友用 AVX2 指令做泰勒展开的加速实现。

参考8 则对利用IEEE-754二进制表示做快速计算的原理进行了初步理解。

5. 完整代码

简单尝试了几个数字, 如 x = 1 x=1 x=1, x = 20 x=20 x=20, x = 40 x=40 x=40, 感觉几个近似实现的误差都略大,打算先用 泰勒展开到精度小于 1 e − 9 1e-9 1e9 的项。本文涉及的所有实现,代码如下:(没有考虑 SIMD/GPU 优化的方法)

#include <stdio.h>
#include <math.h>
#include <stdbool.h>

static double m_fabs(double n)
{
    return n >= 0.0 ? n : -n;
}

double m_exp(double x)
{
    double res = 1;
    double eps = 1e-9;
    double up = 1;
    double down = 1;
    for (int i = 1; ;i++)
    {
        up *= x;
        down *= i;
        double delta = up / down;
        res += delta;
        // printf("i=%d, delta=%lf\n", i, delta);
        if (m_fabs(delta) < eps)
            break;
    }
    return res;
}

double fast_exp(double x)
{
    double d;
    *((int*)&d + 0) = 0;
    *((int*)&d + 1) = (int)(1512775 * x + 1072632447);
    return d;
}

/// e^x = \lim_{n \rightarrow \infty}(1 + \frac{x){n)^n
double exp_by_limit(double x)
{
    x = 1.0 + x / 1024;
    x *= x; x *= x; x *= x; x *= x;
    x *= x; x *= x; x *= x; x *= x;
    x *= x; x *= x;
    return x;
}

// Generated with:
// >>> from math import exp
// >>> [exp(i) for i in range(-710, 710)]
double EXP_TABLE[1420] = {
    4.47628622567513e-309,   1.216780750623423e-308,  3.307553003638408e-308,
    8.99086122645542e-308,   2.443969469407077e-307,  6.643397797997952e-307,
    1.8058627513522668e-306, 4.9088439016919216e-306, 1.334362117671115e-305,
    3.6271722970495225e-305, 9.85967654375977e-305,   2.680137958338607e-304,
    7.285370309915161e-304,  1.9803689727037426e-303, 5.38320099214469e-303,
    1.4633057435889614e-302, 3.977677412277625e-302,  1.0812448229266266e-301,
    2.9391281542768673e-301, 7.98937865328318e-301,   2.171738281389827e-300,
    5.9033967064708435e-300, 1.604709599338467e-299,  4.36205294383555e-299,
    1.185728925200446e-298,  3.223145390850647e-298,  8.76141754643084e-298,
    2.3816002108005187e-297, 6.473860575673281e-297,  1.7597777562830093e-296,
    4.783571897030535e-296,  1.3003096562825466e-295, 3.5346081100426732e-295,
    9.608060996252968e-295,  2.6117417612840555e-294, 7.09945017032607e-294,
    1.929830639004783e-293,  5.245823558010209e-293,  1.4259626853041525e-292,
    3.8761684555229417e-292, 1.0536518276694175e-291, 2.864122616676439e-291,
    7.785492463390136e-291,  2.1163162688838255e-290, 5.752744056979149e-290,
    1.5637579633862188e-289, 4.250734855980884e-289,  1.1554695316610313e-288,
    3.140891831252265e-288,  8.537829190048485e-288,  2.3208225941796005e-287,
    6.30864988483559e-287,   1.714868834405883e-286,  4.661496790756256e-286,
    1.2671262019732887e-285, 3.444406129188316e-285,  9.362866590805559e-285,
    2.5450910116073043e-284, 6.918274648626584e-284,  1.880582026165053e-283,
    5.111951948651156e-283,  1.3895726089974245e-282, 3.7772499723621244e-282,
    1.0267629961419394e-281, 2.791031194546799e-281,  7.586809378798905e-281,
    2.0623086070371722e-280, 5.605936011183831e-280,  1.5238513990705191e-279,
    4.142257567365285e-279,  1.1259823474166023e-278, 3.06073735414821e-278,
    8.319946731466896e-278,  2.261596001389369e-277,  6.14765531389236e-277,
    1.6711059727383288e-276, 4.542536999123976e-276,  1.2347895779821586e-275,
    3.3565060717995146e-275, 9.123929462085072e-275,  2.4801411660927963e-274,
    6.741722663803275e-274,  1.8325902209526951e-273, 4.981496696627458e-273,
    1.3541111948971181e-272, 3.6808558548018004e-272, 1.000560358328482e-271,
    2.7198050403207837e-271, 7.393196618055307e-271,  2.009679202108461e-270,
    5.4628744561235025e-270, 1.4849632365233607e-269, 4.036548581771182e-269,
    1.0972476659520735e-268, 2.982628391676622e-268,  8.107624558140589e-268,
    2.2038808508361863e-267, 5.990769268916865e-267,  1.6284599242187592e-266,
    4.426613020377647e-266,  1.2032781734912767e-265, 3.270849193582728e-265,
    8.891089926545851e-265,  2.4168488182524857e-264, 6.569676224788449e-264,
    1.785823150070186e-263,  4.8543706176772776e-263, 1.3195547438637656e-262,
    3.5869216819018034e-262, 9.750264028019429e-262,  2.6503965530043108e-261,
    7.204524788242109e-261,  1.9583928814561274e-260, 5.3234637826457406e-260,
    1.4470674864825768e-259, 3.933537253059494e-259,  1.069246283655833e-258,
    2.906512743009017e-258,  7.900720773506065e-258,  2.147638571035043e-257,
    5.837886901742308e-257,  1.586902188160519e-256,  4.3136473816186357e-256,
    1.172570929183388e-255,  3.187378249378541e-255,  8.66419237571129e-255,
    2.3551716693169407e-254, 6.402020351605795e-254,  1.740249558719502e-253,
    4.730488752451095e-253,  1.285880161551771e-252,  3.4953846767221607e-252,
    9.501440650208043e-252,  2.582759346364262e-251,  7.020667798504735e-251,
    1.908415370032299e-250,  5.1876108215107433e-250, 1.4101388229230154e-249,
    3.8331547379562597e-249, 1.0419594869858195e-248, 2.832339539464062e-248,
    7.69909710215122e-248,   2.0928315748319355e-247, 5.688906039890977e-247,
    1.5464049912046552e-246, 4.2035645870299835e-246, 1.1426473231677555e-245,
    3.10603745490428e-245,   8.443085172179486e-245,  2.2950684999667505e-244,
    6.238642998528377e-244,  1.6958389897142937e-243, 4.6097683097327105e-243,
    1.2530649429752794e-242, 3.406183664368772e-242,  9.258967159247676e-242,
    2.5168482179282025e-241, 6.841502775783763e-241,  1.8597132674765122e-240,
    5.055224781125599e-240,  1.374152566130957e-239,  3.735333950044147e-239,
    1.0153690399631151e-238, 2.760059210511642e-238,  7.502618797404815e-238,
    2.0394232342840765e-237, 5.543727118291579e-237,  1.5069412687587626e-236,
    4.096291067421963e-236,  1.1134873572652229e-235, 3.02677244947294e-235,
    8.227620548282767e-235,  2.236499142785329e-234,  6.079434979197592e-234,
    1.6525617631251106e-233, 4.492128611109229e-233,  1.2210871574679187e-232,
    3.319259031109752e-232,  9.022681508214216e-232,  2.4526191187752155e-231,
    6.666909982697905e-231,  1.8122540257939923e-230, 4.926217186867559e-230,
    1.3390846662104723e-229, 3.640009514928073e-229,  9.894571719847004e-229,
    2.6896234506444874e-228, 7.311154551284224e-228,  1.987377856181155e-227,
    5.402253112739128e-227,  1.4684846469095084e-226, 3.991755131065214e-226,
    1.0850715436432725e-225, 2.9495302596635135e-225, 8.017654507333419e-225,
    2.179424455414719e-224,  5.924289893653081e-224,  1.610388956444074e-223,
    4.377491037053051e-223,  1.189925434026365e-222,  3.234552684535111e-222,
    8.792425785565214e-222,  2.3900291240976666e-221, 6.496772737522576e-221,
    1.7660059276035744e-220, 4.800501821955756e-220,  1.3049116870106872e-219,
    3.547117726544988e-219,  9.642065659472201e-219,  2.6209851870952265e-218,
    7.124576406741286e-218,  1.9366606581912876e-217, 5.264389475052911e-217,
    1.4310094247967382e-216, 3.8898869157786035e-216, 1.057380891792158e-215,
    2.874259263918443e-215,  7.813046727389575e-215,  2.123806294396449e-214,
    5.773104057224809e-214,  1.5692923852557387e-213, 4.2657789743798256e-213,
    1.1595589470279344e-212, 3.1520080147331386e-212, 8.568046109606362e-212,
    2.329036404514219e-211,  6.3309773362105915e-211, 1.72093806494073e-210,
    4.677994669831859e-210,  1.2716107904632215e-209, 3.4565965045886174e-209,
    9.396003466738291e-209,  2.554098548377289e-208,  6.94275967214761e-208,
    1.8872377456157127e-207, 5.130044069889206e-207,  1.3944905574373912e-206,
    3.790618342239785e-206,  1.0303968958333958e-205, 2.800909158044528e-205,
    7.6136604674769635e-205, 2.069607489679963e-204,  5.6257764312397845e-204,
    1.5292445844012282e-203, 4.1569177650472634e-203, 1.1299674023126563e-202,
    3.071569856457565e-202,  8.349392525651157e-202,  2.2696001981149314e-201,
    6.169412976402867e-201,  1.6770203186015345e-200, 4.55861385801115e-200,
    1.239159721319329e-199,  3.3683853530207066e-199, 9.156220696363793e-199,
    2.4889188336286325e-198, 6.765582837962194e-198,  1.8390760887367006e-197,
    4.999127113166508e-197,  1.3589036389877445e-196, 3.693883068487256e-196,
    1.0041015221521447e-195, 2.7294309215942424e-195, 7.419362476203855e-195,
    2.0167918197815843e-194, 5.482208555497131e-194,  1.4902187896230561e-193,
    4.050834656260586e-193,  1.1011310236205293e-192, 2.993184452260193e-192,
    8.136318905805023e-192,  2.2116807832197573e-191, 6.011971683378335e-191,
    1.6342233380137666e-190, 4.4422796033665057e-190, 1.2075367922765428e-189,
    3.282425319641051e-189,  8.922557099654142e-189,  2.4254024827378097e-188,
    6.592927495525641e-188,  1.7921435007435354e-187, 4.871551112062132e-187,
    1.3242248864327946e-186, 3.5996164455835086e-186, 9.784771973451989e-186,
    2.659776785104989e-185,  7.230022902708112e-185,  1.9653239875774178e-184,
    5.342304482466365e-184,  1.4521889196783625e-183, 3.9474587518512645e-183,
    1.0730305393748917e-182, 2.916799416564376e-182,  7.928682851306888e-182,
    2.1552394518322364e-181, 5.858548237893603e-181,  1.5925185216216938e-180,
    4.328914158808713e-180,  1.1767208694848799e-179, 3.198658956689277e-179,
    8.69485651740623e-179,   2.3635070472324053e-178, 6.424678257926741e-178,
    1.7464086162218176e-177, 4.747230806540073e-177,  1.2904311236918859e-176,
    3.50775547440964e-176,   9.535067964765462e-176,  2.5919001981743924e-175,
    7.04551520987685e-175,   1.9151695967140057e-174, 5.20597071316492e-174,
    1.4151295589086178e-173, 3.84672096489656e-173,   1.0456471698030763e-172,
    2.842363700655332e-172,  7.726345597362994e-172,  2.1002384837706373e-171,
    5.709040105864101e-171,  1.551877997771429e-170,  4.218441761327482e-170,
    1.1466913584229263e-169, 3.1170302824520583e-169, 8.472966775545996e-169,
    2.303191161910391e-168,  6.260722682888491e-168,  1.7018408701917146e-167,
    4.626083112371067e-167,  1.2574997661299533e-166, 3.4182387635625514e-166,
    9.291736316326398e-166,  2.5257557983503035e-165, 6.865716089780698e-165,
    1.8662951286209762e-164, 5.0731161346720364e-164, 1.3790159402541388e-163,
    3.7485539715481897e-163, 1.0189626143857429e-162, 2.7698275585638865e-162,
    7.529171920409294e-162,  2.0466411214592676e-161, 5.5633473698397695e-161,
    1.5122746060840868e-160, 4.110788581358434e-160,  1.1174281901343568e-159,
    3.037484743850101e-159,  8.256739583429307e-159,  2.2444145171954394e-158,
    6.100951197622044e-158,  1.6584104776811452e-157, 4.508027065606742e-157,
    1.2254088054640357e-156, 3.3310064883265936e-156, 9.054614407697357e-156,
    2.4612993808147185e-155, 6.6905053812661495e-155, 1.818667920110323e-154,
    4.9436519592372975e-154, 1.3438239287020702e-153, 3.652892166039281e-153,
    9.92959039626498e-153,   2.6991425138208544e-152, 7.337030047740496e-152,
    1.994411545363099e-151,  5.421372662229435e-151,  1.473681879304291e-150,
    4.00588267344223e-150,   1.0889118078156954e-149, 2.959969179979893e-149,
    8.046030434738165e-149,  2.1871378321977182e-148, 5.9452570255983664e-148,
    1.616088413820251e-147,  4.3929837684707906e-147, 1.1941367950549688e-146,
    3.2460003506922445e-146, 8.823543768458417e-146,  2.398487868841356e-145,
    6.51976598965092e-145,   1.7722561415473398e-144, 4.8174916649430757e-144,
    1.3095300051567673e-143, 3.5596716168395205e-143, 9.676190671336298e-143,
    2.6302613270598386e-142, 7.149791569445333e-142,  1.9435148500492928e-141,
    5.283021100229299e-141,  1.4360740256119015e-140, 3.9036539281428613e-140,
    1.0611231537463512e-139, 2.88443178658586e-139,   7.840698510906002e-139,
    2.131322828462168e-138,  5.793536115188646e-138,  1.5748463944438505e-137,
    4.280876336630965e-137,  1.163662835574428e-136,  3.163163540395093e-136,
    8.59836997230016e-136,   2.337279285007143e-135,  6.353383808468667e-135,
    1.72702877557863e-134,   4.694550937881265e-134,  1.276111250721801e-133,
    3.4688300239292162e-133, 9.429257620059944e-133,  2.563137964446793e-132,
    6.967331352589224e-132,  1.8939170208596268e-131, 5.148200222412013e-131,
    1.3994259113851392e-130, 3.804034025192962e-130,  1.0340436565521947e-129,
    2.8108220814391768e-129, 7.640606587007545e-129,  2.0769322043867094e-128,
    5.645687070125779e-128,  1.5346568571889095e-127, 4.171629847816681e-127,
    1.1339665610377455e-126, 3.082440696949098e-126,  8.378942533819369e-126,
    2.2776327231383779e-125, 6.191247643210744e-125,  1.6829555964029658e-124,
    4.574747615805637e-124,  1.2435453313830803e-123, 3.380306677163709e-123,
    9.188626215152886e-123,  2.4977275669152505e-122, 6.78952745758695e-122,
    1.8455849111782345e-121, 5.016819926933996e-121,  1.3637130444035917e-120,
    3.706956387834846e-120,  1.0076552187941643e-119, 2.7390908706001e-119,
    7.445620940050319e-119,  2.0239296102932935e-118, 5.501611081740457e-118,
    1.4954929430743994e-117, 4.065171291747877e-117,  1.105028125193164e-116,
    3.003777872648744e-116,  8.16511480794845e-116,   2.219508320972814e-115,
    6.033249137014046e-115,  1.6400071495711497e-114, 4.458001633222172e-114,
    1.2118104830828574e-113, 3.2940424157003086e-113, 8.954135640771486e-113,
    2.433986420186662e-112,  6.616261056709485e-112,  1.7984862202794635e-111,
    4.888792411319657e-111,  1.3289115574798703e-110, 3.6123561383267394e-110,
    9.819402048736065e-110,  2.6691902155412764e-109, 7.255611259606534e-109,
    1.9722796241351285e-108, 5.361211862926555e-108,  1.4573284785512322e-107,
    3.961429521341682e-107,  1.0768281882584307e-106, 2.927122496515368e-106,
    7.9567438919514e-106,    2.1628672335193993e-105, 5.8792826982452694e-105,
    1.598154732301378e-104,  4.344234967880666e-104,  1.1808854971746377e-103,
    3.209979588460643e-103,  8.72562918503701e-103,   2.371871925555801e-102,
    6.4474163546704995e-102, 1.7525894717410477e-101, 4.764032113782328e-101,
    1.2949981925089835e-100, 3.5201700545844787e-100, 9.568814292462674e-100,
    2.601073401110048e-99,   7.070450560725609e-99,   1.921947727823849e-98,
    5.22439558379172e-98,    1.4201379580102718e-97,  3.860335205164256e-97,
    1.0493479039958717e-96,  2.852423339163565e-96,   7.753690529920792e-96,
    2.107671607097867e-95,   5.729245429933205e-95,   1.5573703742969461e-94,
    4.23337158863185e-94,    1.1507497062492758e-93,  3.1280620156019908e-93,
    8.502954135303866e-93,   2.3113425714217192e-92,  6.282880511239462e-92,
    1.7078639924081707e-91,  4.642455656042647e-91,   1.2619502849247644e-90,
    3.4303365279297016e-90,  9.324621449370601e-90,   2.534694904308355e-89,
    6.89001509906914e-89,    1.8729002841608093e-88,  5.09107080895011e-88,
    1.3838965267367376e-87,  3.761820781096061e-87,   1.0225689071173033e-86,
    2.779630478564191e-86,   7.555819019711961e-86,   2.0538845540408258e-85,
    5.583037061001886e-85,   1.5176268190534823e-84,  4.125337404615185e-84,
    1.1213829703227856e-83,  3.0482349509718567e-83,  8.285961676100547e-83,
    2.252357905545217e-82,   6.122543565829638e-82,   1.664279891894355e-81,
    4.52398178760621e-81,    1.2297457485529627e-80,  3.3427955219162848e-80,
    9.086660323479307e-80,   2.470010363869359e-79,   6.714184288211594e-79,
    1.8251045143570802e-78,  4.961148436415422e-78,   1.3485799642996046e-77,
    3.665820411179563e-77,   9.964733010103672e-77,   2.7086952666810816e-76,
    7.362997122252211e-76,   2.001470128041443e-75,   5.440559879258653e-75,
    1.4788975056432133e-74,  4.020060215743355e-74,   1.0927656633766312e-73,
    2.970445045520691e-73,   8.074506789675094e-73,   2.194878508014299e-72,
    5.96629836401057e-72,    1.6218080426054863e-71,  4.408531331463226e-71,
    1.1983630608508849e-70,  3.257488532207521e-70,   8.854771883513433e-70,
    2.4069765506104637e-69,  6.542840619051457e-69,   1.7785284761271306e-68,
    4.834541638053336e-68,   1.314164668364901e-67,   3.5722699376192174e-67,
    9.710436457780846e-67,   2.6395702969591894e-66,  7.175095973164411e-66,
    1.9503933001302485e-65,  5.301718666092324e-65,   1.4411565509640892e-64,
    3.917469664450395e-64,   1.0648786602415064e-63,  2.8946403116483003e-63,
    7.868448159078602e-63,   2.138865964899539e-62,   5.814040485895939e-62,
    1.580420060273613e-61,   4.2960271311739114e-61,  1.1677812485237086e-60,
    3.1743585474772134e-60,  8.628801156620959e-60,   2.3455513385429143e-59,
    6.375869581278994e-59,   1.733141042341547e-58,   4.7111658015535965e-58,
    1.2806276389220833e-57,  3.4811068399043105e-57,  9.462629465836378e-57,
    2.572209372642415e-56,   6.991989996645917e-56,   1.9006199352650016e-55,
    5.166420632837861e-55,   1.4043787324419038e-54,  3.817497188671175e-54,
    1.0377033238158346e-53,  2.820770088460135e-53,   7.667648073722e-53,
    2.0842828425817514e-52,  5.665668176358939e-52,   1.5400882849875202e-51,
    4.1863939993042314e-51,  1.1379798735078682e-50,  3.093350011308561e-50,
    8.408597124803643e-50,   2.2856936767186716e-49,  6.213159586848109e-49,
    1.6889118802245324e-48,  4.590938473882946e-48,   1.2479464629129513e-47,
    3.392270193026015e-47,   9.221146422925876e-47,   2.506567475899953e-46,
    6.813556821545298e-46,   1.8521167695179754e-45,  5.0345753587649823e-45,
    1.368539471173853e-44,   3.720075976020836e-44,   1.0112214926104486e-43,
    2.7487850079102147e-43,  7.47197233734299e-43,    2.031092662734811e-42,
    5.5210822770285325e-42,  1.5007857627073948e-41,  4.0795586671775603e-41,
    1.1089390193121365e-40,  3.0144087850653746e-40,  8.194012623990515e-40,
    2.2273635617957438e-39,  6.054601895401186e-39,   1.6458114310822737e-38,
    4.4737793061811207e-38,  1.2160992992528256e-37,  3.3057006267607343e-37,
    8.985825944049381e-37,   2.4426007377405277e-36,  6.639677199580735e-36,
    1.8048513878454153e-35,  4.906094730649281e-35,   1.3336148155022614e-34,
    3.6251409191435593e-34,  9.854154686111257e-34,   2.6786369618080778e-33,
    7.281290178321643e-33,   1.9792598779469045e-32,  5.380186160021138e-32,
    1.462486227251231e-31,   3.975449735908647e-31,   1.0806392777072785e-30,
    2.9374821117108028e-30,  7.984904245686979e-30,   2.1705220113036395e-29,
    5.900090541597061e-29,   1.603810890548638e-28,   4.359610000063081e-28,
    1.185064864233981e-27,   3.221340285992516e-27,   8.75651076269652e-27,
    2.3802664086944007e-26,  6.47023492564546e-26,    1.7587922024243116e-25,
    4.780892883885469e-25,   1.2995814250075031e-24,  3.532628572200807e-24,
    9.602680054508676e-24,   2.6102790696677047e-23,  7.095474162284704e-23,
    1.9287498479639178e-22,  5.242885663363464e-22,   1.4251640827409352e-21,
    3.873997628687187e-21,   1.0530617357553812e-20,  2.8625185805493937e-20,
    7.781132241133797e-20,   2.1151310375910805e-19,  5.74952226429356e-19,
    1.5628821893349888e-18,  4.248354255291589e-18,   1.1548224173015786e-17,
    3.1391327920480296e-17,  8.533047625744066e-17,   2.3195228302435696e-16,
    6.305116760146989e-16,   1.713908431542013e-15,   4.658886145103398e-15,
    1.2664165549094176e-14,  3.442477108469977e-14,   9.357622968840175e-14,
    2.543665647376923e-13,   6.914400106940203e-13,   1.8795288165390832e-12,
    5.109089028063325e-12,   1.3887943864964021e-11,  3.775134544279098e-11,
    1.026187963170189e-10,   2.7894680928689246e-10,  7.582560427911907e-10,
    2.061153622438558e-09,   5.602796437537268e-09,   1.522997974471263e-08,
    4.139937718785167e-08,   1.1253517471925912e-07,  3.059023205018258e-07,
    8.315287191035679e-07,   2.2603294069810542e-06,  6.14421235332821e-06,
    1.670170079024566e-05,   4.5399929762484854e-05,  0.00012340980408667956,
    0.00033546262790251185,  0.0009118819655545162,   0.0024787521766663585,
    0.006737946999085467,    0.01831563888873418,     0.049787068367863944,
    0.1353352832366127,      0.36787944117144233,     1.0,
    2.718281828459045,       7.38905609893065,        20.085536923187668,
    54.598150033144236,      148.4131591025766,       403.4287934927351,
    1096.6331584284585,      2980.9579870417283,      8103.083927575384,
    22026.465794806718,      59874.14171519782,       162754.79141900392,
    442413.3920089205,       1202604.2841647768,      3269017.3724721107,
    8886110.520507872,       24154952.7535753,        65659969.13733051,
    178482300.96318725,      485165195.4097903,       1318815734.4832146,
    3584912846.131592,       9744803446.248903,       26489122129.84347,
    72004899337.38588,       195729609428.83878,      532048240601.79865,
    1446257064291.475,       3931334297144.042,       10686474581524.463,
    29048849665247.426,      78962960182680.69,       214643579785916.06,
    583461742527454.9,       1586013452313430.8,      4311231547115195.0,
    1.1719142372802612e+16,  3.1855931757113756e+16,  8.659340042399374e+16,
    2.3538526683702e+17,     6.398434935300549e+17,   1.739274941520501e+18,
    4.727839468229346e+18,   1.2851600114359308e+19,  3.4934271057485095e+19,
    9.496119420602448e+19,   2.5813128861900675e+20,  7.016735912097631e+20,
    1.9073465724950998e+21,  5.184705528587072e+21,   1.4093490824269389e+22,
    3.831008000716577e+22,   1.0413759433029089e+23,  2.830753303274694e+23,
    7.694785265142018e+23,   2.091659496012996e+24,   5.685719999335932e+24,
    1.545538935590104e+25,   4.2012104037905144e+25,  1.1420073898156842e+26,
    3.10429793570192e+26,    8.438356668741454e+26,   2.29378315946961e+27,
    6.235149080811617e+27,   1.6948892444103338e+28,  4.607186634331292e+28,
    1.2523631708422137e+29,  3.404276049931741e+29,   9.253781725587787e+29,
    2.515438670919167e+30,   6.837671229762744e+30,   1.8586717452841279e+31,
    5.052393630276104e+31,   1.3733829795401761e+32,  3.7332419967990015e+32,
    1.0148003881138887e+33,  2.7585134545231703e+33,  7.498416996990121e+33,
    2.0382810665126688e+34,  5.54062238439351e+34,    1.5060973145850306e+35,
    4.0939969621274545e+35,  1.1128637547917594e+36,  3.0250773222011426e+36,
    8.223012714622913e+36,   2.235246603734715e+37,   6.076030225056872e+37,
    1.6516362549940018e+38,  4.4896128191743455e+38,  1.2204032943178408e+39,
    3.317400098335743e+39,   9.017628405034299e+39,   2.451245542920086e+40,
    6.663176216410896e+40,   1.8112390828890233e+41,  4.923458286012058e+41,
    1.3383347192042695e+42,  3.637970947608805e+42,   9.889030319346946e+42,
    2.6881171418161356e+43,  7.307059979368067e+43,   1.9862648361376543e+44,
    5.399227610580169e+44,   1.4676622301554424e+45,  3.989519570547216e+45,
    1.0844638552900231e+46,  2.947878391455509e+46,   8.013164264000591e+46,
    2.1782038807290206e+47,  5.92097202766467e+47,    1.609487066961518e+48,
    4.375039447261341e+48,   1.189259022828201e+49,   3.2327411910848595e+49,
    8.787501635837023e+49,   2.3886906014249913e+50,  6.493134255664462e+50,
    1.7650168856917655e+51,  4.797813327299302e+51,   1.3041808783936323e+52,
    3.5451311827611664e+52,  9.636665673603202e+52,   2.6195173187490626e+53,
    7.120586326889338e+53,   1.9355760420357226e+54,  5.261441182666386e+54,
    1.4302079958348105e+55,  3.887708405994595e+55,   1.0567887114362587e+56,
    2.872649550817832e+56,   7.808671073519151e+56,   2.1226168683560893e+57,
    5.769870862033003e+57,   1.568413511681964e+58,   4.263389948314721e+58,
    1.1589095424138854e+59,  3.150242749971452e+59,   8.56324762248225e+59,
    2.3277320404788622e+60,  6.327431707155585e+60,   1.7199742630376623e+61,
    4.675374784632515e+61,   1.2708986318302189e+62,  3.454660656717546e+62,
    9.390741286647697e+62,   2.5526681395254553e+63,  6.938871417758404e+63,
    1.886180808490652e+64,   5.12717101690833e+64,    1.3937095806663797e+65,
    3.788495427274696e+65,   1.0298198277160991e+66,  2.799340524267497e+66,
    7.609396478785354e+66,   2.0684484173822473e+67,  5.622625746075033e+67,
    1.5283881393781746e+68,  4.154589706104022e+68,   1.129334570280557e+69,
    3.0698496406442424e+69,  8.344716494264775e+69,   2.2683291210002403e+70,
    6.165957830579433e+70,   1.6760811125908828e+71,  4.556060831379215e+71,
    1.2384657367292132e+72,  3.366498907320164e+72,   9.151092805295634e+72,
    2.487524928317743e+73,   6.761793810485009e+73,   1.8380461242828246e+74,
    4.996327379507578e+74,   1.358142592474785e+75,   3.691814329580466e+75,
    1.0035391806143295e+76,  2.7279023188106115e+76,  7.415207303034179e+76,
    2.0156623266094611e+77,  5.47913827473198e+77,    1.4893842007818383e+78,
    4.048566008579269e+78,   1.1005143412437996e+79,  2.991508135761597e+79,
    8.131762205128143e+79,   2.2104421435549888e+80,  6.008604711685586e+80,
    1.633308100216833e+81,   4.4397917290943824e+81,  1.2068605179340022e+82,
    3.2805870153846705e+82,  8.917560070598843e+82,   2.4240441494100796e+83,
    6.589235162723882e+83,   1.7911398206275708e+84,  4.8688228266413195e+84,
    1.3234832615645704e+85,  3.5976005001806814e+85,  9.779292065696318e+85,
    2.658287191737602e+86,   7.225973768125749e+86,   1.964223318681796e+87,
    5.339312554208246e+87,   1.4513756292567526e+88,  3.945247999276943e+88,
    1.0724295945198918e+89,  2.9151658790851237e+89,  7.924242436060931e+89,
    2.1540324218248465e+90,  5.855267190158109e+90,   1.5916266403779241e+91,
    4.326489774230631e+91,   1.1760618534305e+92,     3.196867565323994e+92,
    8.689987010810322e+92,   2.3621833781030834e+93,  6.421080152185614e+93,
    1.7454305496765193e+94,  4.744572146022966e+94,   1.2897084248347162e+95,
    3.505790975238748e+95,   9.529727902367202e+95,   2.5904486187163903e+96,
    7.041569407813597e+96,   1.9140970165092822e+97,  5.2030551378848545e+97,
    1.4143370233782872e+98,  3.844566629966054e+98,   1.0450615608536755e+99,
    2.840771850489593e+99,   7.722018499983836e+99,   2.0990622567530634e+100,
    5.705842789336087e+100,  1.551008877029636e+101,  4.216079246208329e+101,
    1.146049160231141e+102,  3.115284606777059e+102,  8.468221537080262e+102,
    2.30190127236108e+103,   6.25721639956588e+103,   1.700887763567586e+104,
    4.6234922999541146e+104, 1.2567955102985587e+105, 3.416324397733485e+105,
    9.286532530480224e+105,  2.5243412626998188e+106, 6.861870983226278e+106,
    1.8652499202934394e+107, 5.070274963868339e+107,  1.3782436299574147e+108,
    3.7464546145026734e+108, 1.0183919499749154e+109, 2.7682763318657856e+109,
    7.524955249064026e+109,  2.045494911349825e+110,  5.5602316477276757e+110,
    1.5114276650041035e+111, 4.10848635681094e+111,   1.1168023806191083e+112,
    3.0357836172167243e+112, 8.25211544181389e+112,   2.2431575451828986e+113,
    6.0975343934414735e+113, 1.6574816940096004e+114, 4.505502369829812e+114,
    1.2247225219987542e+115, 3.329140976453747e+115,  9.049543420672623e+115,
    2.45992094362655e+116,   6.686758400505878e+116,  1.8176493851391e+117,
    4.940883294133372e+117,  1.3430713274979614e+118, 3.6508463838620755e+118,
    9.924029383747696e+118,  2.6976308738934977e+119, 7.33292098439479e+119,
    1.993294586140637e+120,  5.418336452271886e+120,  1.472856551868792e+121,
    4.0036392008717847e+121, 1.0883019687436065e+122, 2.9583114655119493e+122,
    8.04152429962318e+122,   2.185912937677754e+123,  5.941927417082968e+123,
    1.6151833323879222e+124, 4.390523502060015e+124,  1.1934680253072109e+125,
    3.2441824460394912e+125, 8.818602191274965e+125,  2.3971446088951858e+126,
    6.516114630548348e+126,  1.77126359923757e+127,   4.814793655218451e+127,
    1.3087966100760222e+128, 3.55767804231845e+128,   9.670771573941992e+128,
    2.6287882636624796e+129, 7.145787367980123e+129,  1.9424263952412558e+130,
    5.280062373303513e+130,  1.435269760248128e+131,  3.901467708219257e+131,
    1.0605288775572162e+132, 2.882816376419849e+132,  7.836307370806225e+132,
    2.130129192828224e+133,  5.790291477135095e+133,  1.5739644103777611e+134,
    4.278478855371123e+134,  1.1630111326001581e+135, 3.161392028042583e+135,
    8.593554502463442e+135,  2.3359703045918785e+136, 6.349825630792043e+136,
    1.7260615626065507e+137, 4.691921780435012e+137,  1.2753965716307703e+138,
    3.4668873247428877e+138, 9.423976816163585e+138,  2.56170249311968e+139,
    6.963429336965459e+139,  1.8928563430431824e+140, 5.145317001177723e+140,
    1.3986421705962793e+141, 3.801903596848382e+141,  1.0334645460866042e+142,
    2.8092478959838913e+142, 7.636327507289818e+142,  2.075769029922787e+143,
    5.642525234117172e+143,  1.533797381052233e+144,  4.169293549452358e+144,
    1.133331489298786e+145,  3.080714392981317e+145,  8.374249953113352e+145,
    2.2763571474522036e+146, 6.187780269002192e+146,  1.682013066372608e+147,
    4.572185553551339e+147,  1.2428488906561565e+148, 3.378413554991113e+148,
    9.183480175552067e+148,  2.4963287283217065e+149, 6.785725020057171e+149,
    1.8445513014941297e+150, 5.014010284511975e+150,  1.362949304409567e+151,
    3.7048803272874213e+151, 1.0070908870280797e+152, 2.7375568578151306e+152,
    7.441451060972311e+152,  2.0227961196408315e+153, 5.498529934697141e+153,
    1.4946554004725342e+154, 4.062894614912666e+154,  1.1044092602661211e+155,
    3.0020956233632933e+155, 8.16054198028487e+155,   2.2182652975385555e+156,
    6.0298702490003525e+156, 1.6390886725823477e+157, 4.4555049539136534e+157,
    1.211131815283274e+158,  3.2921976053531405e+158, 8.949120926327824e+158,
    2.4326232794719504e+159, 6.612555656075053e+159,  1.7974789879582895e+160,
    4.8860544700039736e+160, 1.3281673078672893e+161, 3.6103330581290227e+161,
    9.813902746597095e+161,  2.66769535023392e+162,   7.251547794405553e+162,
    1.9711750597734883e+163, 5.358209345693946e+163,  1.4565123097479284e+164,
    3.959210944514706e+164,  1.0762251165510499e+165, 2.9254831776519365e+165,
    7.952287761273885e+165,  2.161655931614806e+166,  5.875990038289236e+166,
    1.5972596945288e+167,    4.3418020029676826e+167, 1.1802241487434137e+168,
    3.2081818570377667e+168, 8.720742444377757e+168,  2.370543571722357e+169,
    6.443805514583285e+169,  1.7516079436415928e+170, 4.7613640437854577e+170,
    1.2942729358900287e+171, 3.518198602696204e+171,  9.563455330619095e+171,
    2.5996166842501676e+172, 7.066490793756186e+172,  1.9208713515640576e+173,
    5.221469689764144e+173,  1.419342617553556e+174,  3.858173245653328e+174,
    1.0487602224706297e+175, 2.8508258551525784e+175, 7.749348118162471e+175,
    2.1064912172004347e+176, 5.726036797524517e+176,  1.556498177579872e+177,
    4.231000712144986e+177,  1.1501052352020995e+178, 3.1263101616654833e+178,
    8.498192102582143e+178,  2.3100481167203208e+179, 6.279361818546888e+179,
    1.7069075125675549e+180, 4.639855674272614e+180,  1.2612435366047836e+181,
    3.428415386814204e+181,  9.31939924638644e+181,   2.5332753623607178e+182,
    6.886156383988143e+182,  1.8718513766522217e+183, 5.088219582729782e+183,
    1.3831214830943832e+184, 3.759713994046786e+184,  1.0219962230220558e+185,
    2.778073761794632e+185,  7.551587424805211e+185,  2.052734287286784e+186,
    5.579910311786494e+186,  1.5167768804960472e+187, 4.123027032079202e+187,
    1.1207549459546325e+188, 3.046527803744077e+188,  8.281321168812768e+188,
    2.2510964848816967e+189, 6.119114668961948e+189,  1.663347821089645e+190,
    4.521448156474929e+190,  1.229057036206545e+191,  3.340923407659982e+191,
    9.0815713893156e+191,    2.4686270481430163e+192, 6.710424046209653e+192,
    1.8240823746066321e+193, 4.958369972505633e+193,  1.3478246995039038e+194,
    3.663767388609735e+194,  9.959152316158692e+194,  2.7071782767869983e+195,
    7.35887351618917e+195,   2.000349215698554e+196,  5.437512923605682e+196,
    1.4780692572248542e+197, 4.017808803118279e+197,  1.0921536659739205e+198,
    2.968781464101838e+198,  8.069984706534065e+198,  2.193649278371395e+199,
    5.962956971409261e+199,  1.6208997579264978e+200, 4.4060623577252635e+200,
    1.1976919242062002e+201, 3.255664193661862e+201,  8.849812817195809e+201,
    2.405628536624732e+202,  6.539176337129533e+202,  1.777532421030859e+203,
    4.831834079584997e+203,  1.3134286776665033e+204, 3.5702693074778485e+204,
    9.704998181222095e+204,  2.6380920201244107e+205, 7.1710776001069995e+205,
    1.9493009930840557e+206, 5.298749467697559e+206,  1.4403494391599313e+207,
    3.9152757070996186e+207, 1.0642822808016033e+208, 2.8930191842539453e+208,
    7.86404147794091e+208,   2.137668104773499e+209,  5.810784364482288e+209,
    1.5795349547066147e+210, 4.2936211647948715e+210, 1.167127239054906e+211,
    3.172580765422527e+211,  8.623968643966744e+211,  2.3442377254095393e+212,
    6.372298810568915e+212,  1.732170406228067e+213,  4.708527339044277e+213,
    1.279910430452668e+214,  3.4791572651546824e+214, 9.457329972221242e+214,
    2.5707688209230085e+215, 6.9880741710841e+215,    1.8995555035181914e+216,
    5.1635272073628715e+216, 1.4035922178528375e+217, 3.8153592203558975e+217,
    1.0371221637737106e+218, 2.8191903316782035e+218, 7.663353849568289e+218,
    2.0831155514333153e+219, 5.662495150041624e+219,  1.5392257670095623e+220,
    4.184049432358029e+220,  1.1373425541353215e+221, 3.091617597639242e+221,
    8.403887936206959e+221,  2.2844135865397565e+222, 6.209679940975975e+222,
    1.687966014410163e+223,  4.588367344027585e+223,  1.2472475573565076e+224,
    3.3903703707521256e+224, 9.215982170561459e+224,  2.505163686563976e+225,
    6.809740926502327e+225,  1.851079501702514e+226,  5.031755772510968e+226,
    1.367773028166047e+227,  3.7179925679201674e+227, 1.0106551635723174e+228,
    2.7472455659769343e+228, 7.467787700309786e+228,  2.0299551604542052e+229,
    5.517990225249331e+229,  1.4999452558909891e+230, 4.077273932771829e+230,
    1.1083179641103409e+231, 3.0127205819958637e+231, 8.189423612263916e+231,
    2.2261161390770435e+232, 6.051211048892536e+232,  1.644889703437518e+233,
    4.471273790673593e+233,  1.2154182295253221e+234, 3.3038492872965484e+234,
    8.980793481625574e+234,  2.441232772624624e+235,  6.635958684864208e+235,
    1.803840590747136e+236,  4.903347099264769e+236,  1.3328679318558793e+237,
    3.6231106788996255e+237, 9.848635920948766e+237,  2.6771368059024047e+238,
    7.277212331783397e+238,  1.9781514043324884e+239, 5.377173016337745e+239,
    1.4616671698791204e+240, 3.9732233071375736e+240, 1.0800340716202018e+241,
    2.935836991001829e+241,  7.980432343958154e+241,  2.1693064223828275e+242,
    5.896786228322743e+242,  1.6029126850757262e+243, 4.357168424447843e+243,
    1.1844011751712099e+244, 3.219536192073438e+244,  8.751606726979457e+244,
    2.37893335357682e+245,   6.4666113061430065e+245, 1.757807200519635e+246,
    4.778215371106989e+246,  1.298853601574382e+247,  3.5306501429882274e+247,
    9.597302126331227e+247,  2.608817197223753e+248,  7.091500380984786e+248,
    1.9276696622141338e+249, 5.239949414068466e+249,  1.4243659274306933e+250,
    3.871828017611069e+250,  1.0524719743190776e+251, 2.860915442753964e+251,
    7.776774460795963e+251,  2.1139464700806057e+252, 5.746302275955253e+252,
    1.5620069057562017e+253, 4.245974987844624e+253,  1.1541756653549656e+254,
    3.137374737984031e+254,  8.52826873932845e+254,   2.3182237942331857e+255,
    6.301585614165449e+255,  1.7129485665464872e+256, 4.656276961528286e+256,
    1.2657073052794837e+257, 3.440549168089086e+257,  9.352382283536447e+257,
    2.5422410814139436e+258, 6.910527735169595e+258,  1.878476196757375e+259,
    5.106227710838431e+259,  1.3880165998346134e+260, 3.7730203009299397e+260,
    1.0256132522424933e+261, 2.787905866597553e+261,  7.578313856626495e+261,
    2.059999284682719e+262,  5.599658622191666e+262,  1.522145027827762e+263,
    4.1376191694234934e+263, 1.124721500132769e+264,  3.0573100158881035e+264,
    8.310630260154467e+264,  2.2590635219219752e+265, 6.140771320975197e+265,
    1.6692347094529326e+266, 4.537450378139021e+266,  1.2334068910429924e+267,
    3.352747539018332e+267,  9.113712710724316e+267,  2.4773639651358133e+268,
    6.734173448907929e+268,  1.83053813158578e+269,   4.975918539390998e+269,
    1.3525948945519025e+270, 3.676734123126915e+270,  9.994399554971195e+270,
    2.7167594696637367e+271, 7.384917898680968e+271,  2.007428812864643e+272,
    5.456757263935073e+272,  1.4833004112866607e+273, 4.032028554146358e+273,
    1.0960189950564043e+274, 2.9792885179077677e+274, 8.098545839965366e+274,
    2.201412999372045e+275,  5.984060953126553e+275,  1.6266364149275224e+276,
    4.421656208207252e+276,  1.2019307722462898e+277, 3.2671865772628366e+277,
    8.881133903158874e+277,  2.414142490506832e+278,  6.562319663255584e+278,
    1.7838234293167135e+279, 4.848934813091121e+279,  1.318077138980805e+280,
    3.58290513539881e+280,   9.73934592264718e+280,   2.6474287042608523e+281,
    7.19645733893315e+281,   1.956199921370272e+282,  5.317502699093823e+282,
    1.4454470959728667e+283, 3.9291325749819406e+283, 1.0680489680179907e+284,
    2.9032581016677402e+284, 7.891873741089921e+284,  2.1452336982897837e+285,
    5.831349779859113e+285,  1.585125214197968e+286,  4.308817065586588e+286,
    1.1712579131538248e+287, 3.1838091017649045e+287, 8.654490426610056e+287,
    2.3525344061226884e+288, 6.394851526987996e+288,  1.7383008701505047e+289,
    4.725191667724663e+289,  1.2844402646362043e+290, 3.491470631101721e+290,
    9.490801171122244e+290,  2.579867236097942e+291,  7.012806227721897e+291,
    1.9062783735320858e+292, 5.181801862756733e+292,  1.4085597842206858e+293,
    3.828862465745284e+293,  1.04079272643043e+294,   2.829167955448184e+294,
    7.690475842953428e+294,  2.090488073610356e+295,  5.682535743105387e+295,
    1.5446733650052388e+296, 4.198857538998427e+296,  1.1413678148547691e+297,
    3.1025593907077266e+297, 8.433630813475781e+297,  2.2924985388203488e+298,
    6.231657119844268e+298,  1.6939400310060103e+299, 4.60460640478299e+299,
    1.2516617917327736e+300, 3.4023695038436884e+300, 9.248599196001516e+300,
    2.5140299133191857e+301, 6.833841829578011e+301,  1.8576308063905224e+302,
    5.049564064997079e+302,  1.372613823952135e+303,  3.7311512151407716e+303,
    1.0142320547350045e+304, 2.7569685642268427e+304, 7.49421754977065e+304,
    2.037139538406043e+305,  5.5375193892845935e+305, 1.505253833063194e+306,
    4.0917041416340054e+306, 1.1122405015634333e+307, 3.023383144276055e+307,
    8.218407461554972e+307
};

double fast_exp_by_lut(double x)
{
    double integer = (int)x;
    // x is now the fractional part of the number.
    x = x - integer;

    // Use a 4-part polynomial to approximate exp(x);
    double c[] = { 0.28033708, 0.425302, 1.01273643, 1.00020947 };

    // Use Horner's method to evaluate the polynomial.
    double val = c[3] + x * (c[2] + x * (c[1] + x * (c[0])));
    return val * EXP_TABLE[(unsigned)integer + 710];
}

int main()
{
    double x;
    while (true)
    {
        printf("Please input double value x: ");
        scanf("%lf", &x);
        double y = m_exp(x);
        double gt = exp(x);
        double diff1 = m_fabs(y - gt);
        double fy = fast_exp(x);
        double diff2 = m_fabs(gt - fy);
        double z = fast_exp_by_lut(x);
        double uu = exp_by_limit(x);
        printf(" exp(%lf) = %lf\n", x, y);
        printf(" m_exp(%lf) = %lf\n", x, gt);
        printf(" exp_by_limit(%lf) = %lf\n", x, uu);
        printf(" fast_exp(%lf) = %lf\n", x, fy);
        printf(" fast_exp_by_lut(%lf) = %lf\n", x, z);
        printf(" abs(exp(%lf) - m_exp(%lf)) = %lf, %lf\n", x, x, diff1, gt-y);
        //printf("diff1 = %lf\n", diff1);
        printf(" abs(exp(%lf) - fast_exp(%lf) = %lf\n", x, x, diff2);
    }
    return 0;
}

6. References


  1. exp近似计算,exp快速算法,C语言实现exp ↩︎

  2. https://blog.csdn.net/just_sort/article/details/88128200 ↩︎

  3. Fastest Implementation of the Natural Exponential Function Using SSE ↩︎

  4. 这个求指数函数exp()的快速近似方法的原理是什么? ↩︎

  5. 一种快速的幂运算方法(底数是自然数e,指数是浮点数) ↩︎

  6. Logarithmic and Exponential Function Approximation ↩︎

  7. A Fast, Compact Approximation of the Exponential Function ↩︎

  8. avx2实现exp函数的快速近似计算 ↩︎

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值