using System;
using System.Diagnostics;
namespace fastexponent
{
class Program
{
static double[] ExpAdjustment = new double[256] {
1.040389835,
1.039159306,
1.037945888,
1.036749401,
1.035569671,
1.034406528,
1.033259801,
1.032129324,
1.031014933,
1.029916467,
1.028833767,
1.027766676,
1.02671504,
1.025678708,
1.02465753,
1.023651359,
1.022660049,
1.021683458,
1.020721446,
1.019773873,
1.018840604,
1.017921503,
1.017016438,
1.016125279,
1.015247897,
1.014384165,
1.013533958,
1.012697153,
1.011873629,
1.011063266,
1.010265947,
1.009481555,
1.008709975,
1.007951096,
1.007204805,
1.006470993,
1.005749552,
1.005040376,
1.004343358,
1.003658397,
1.002985389,
1.002324233,
1.001674831,
1.001037085,
1.000410897,
0.999796173,
0.999192819,
0.998600742,
0.998019851,
0.997450055,
0.996891266,
0.996343396,
0.995806358,
0.995280068,
0.99476444,
0.994259393,
0.993764844,
0.993280711,
0.992806917,
0.992343381,
0.991890026,
0.991446776,
0.991013555,
0.990590289,
0.990176903,
0.989773325,
0.989379484,
0.988995309,
0.988620729,
0.988255677,
0.987900083,
0.987553882,
0.987217006,
0.98688939,
0.98657097,
0.986261682,
0.985961463,
0.985670251,
0.985387985,
0.985114604,
0.984850048,
0.984594259,
0.984347178,
0.984108748,
0.983878911,
0.983657613,
0.983444797,
0.983240409,
0.983044394,
0.982856701,
0.982677276,
0.982506066,
0.982343022,
0.982188091,
0.982041225,
0.981902373,
0.981771487,
0.981648519,
0.981533421,
0.981426146,
0.981326648,
0.98123488,
0.981150798,
0.981074356,
0.981005511,
0.980944219,
0.980890437,
0.980844122,
0.980805232,
0.980773726,
0.980749562,
0.9807327,
0.9807231,
0.980720722,
0.980725528,
0.980737478,
0.980756534,
0.98078266,
0.980815817,
0.980855968,
0.980903079,
0.980955475,
0.981017942,
0.981085714,
0.981160303,
0.981241675,
0.981329796,
0.981424634,
0.981526154,
0.981634325,
0.981749114,
0.981870489,
0.981998419,
0.982132873,
0.98227382,
0.982421229,
0.982575072,
0.982735318,
0.982901937,
0.983074902,
0.983254183,
0.983439752,
0.983631582,
0.983829644,
0.984033912,
0.984244358,
0.984460956,
0.984683681,
0.984912505,
0.985147403,
0.985388349,
0.98563532,
0.98588829,
0.986147234,
0.986412128,
0.986682949,
0.986959673,
0.987242277,
0.987530737,
0.987825031,
0.988125136,
0.98843103,
0.988742691,
0.989060098,
0.989383229,
0.989712063,
0.990046579,
0.990386756,
0.990732574,
0.991084012,
0.991441052,
0.991803672,
0.992171854,
0.992545578,
0.992924825,
0.993309578,
0.993699816,
0.994095522,
0.994496677,
0.994903265,
0.995315266,
0.995732665,
0.996155442,
0.996583582,
0.997017068,
0.997455883,
0.99790001,
0.998349434,
0.998804138,
0.999264107,
0.999729325,
1.000199776,
1.000675446,
1.001156319,
1.001642381,
1.002133617,
1.002630011,
1.003131551,
1.003638222,
1.00415001,
1.004666901,
1.005188881,
1.005715938,
1.006248058,
1.006785227,
1.007327434,
1.007874665,
1.008426907,
1.008984149,
1.009546377,
1.010113581,
1.010685747,
1.011262865,
1.011844922,
1.012431907,
1.013023808,
1.013620615,
1.014222317,
1.014828902,
1.01544036,
1.016056681,
1.016677853,
1.017303866,
1.017934711,
1.018570378,
1.019210855,
1.019856135,
1.020506206,
1.02116106,
1.021820687,
1.022485078,
1.023154224,
1.023828116,
1.024506745,
1.025190103,
1.02587818,
1.026570969,
1.027268461,
1.027970647,
1.02867752,
1.029389072,
1.030114973,
1.030826088,
1.03155163,
1.032281819,
1.03301665,
1.033756114,
1.034500204,
1.035248913,
1.036002235,
1.036760162,
1.037522688,
1.038289806,
1.039061509,
1.039837792,
1.040618648
};
static double FastExp(double x)
{
var tmp = (long)(1512775 * x + 1072632447);
int index = (int)(tmp >> 12) & 0xFF;
return BitConverter.Int64BitsToDouble(tmp << 32) * ExpAdjustment[index];
}
static void Main(string[] args)
{
double[] x = new double[1000000];
double[] ex = new double[x.Length];
double[] fx = new double[x.Length];
Random r = new Random();
for (int i = 0; i < x.Length; ++i)
x[i] = r.NextDouble() * 40;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int j = 0; j < x.Length; ++j)
ex[j] = Math.Exp(x[j]);
sw.Stop();
double builtin = sw.Elapsed.TotalMilliseconds;
sw.Reset();
sw.Start();
for (int k = 0; k < x.Length; ++k)
fx[k] = FastExp(x[k]);
sw.Stop();
double custom = sw.Elapsed.TotalMilliseconds;
double min = 1, max = 1;
for (int m = 0; m < x.Length; ++m) {
double ratio = fx[m] / ex[m];
if (min > ratio) min = ratio;
if (max < ratio) max = ratio;
}
Console.WriteLine("minimum ratio = " + min.ToString() + ", maximum ratio = " + max.ToString() + ", speedup = " + (builtin / custom).ToString());
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uRGlhZ25vc3RpY3M7CgpuYW1lc3BhY2UgZmFzdGV4cG9uZW50CnsKCWNsYXNzIFByb2dyYW0KCXsKCQlzdGF0aWMgZG91YmxlW10gRXhwQWRqdXN0bWVudCA9IG5ldyBkb3VibGVbMjU2XSB7CgkJCTEuMDQwMzg5ODM1LAoJCQkxLjAzOTE1OTMwNiwKCQkJMS4wMzc5NDU4ODgsCgkJCTEuMDM2NzQ5NDAxLAoJCQkxLjAzNTU2OTY3MSwKCQkJMS4wMzQ0MDY1MjgsCgkJCTEuMDMzMjU5ODAxLAoJCQkxLjAzMjEyOTMyNCwKCQkJMS4wMzEwMTQ5MzMsCgkJCTEuMDI5OTE2NDY3LAoJCQkxLjAyODgzMzc2NywKCQkJMS4wMjc3NjY2NzYsCgkJCTEuMDI2NzE1MDQsCgkJCTEuMDI1Njc4NzA4LAoJCQkxLjAyNDY1NzUzLAoJCQkxLjAyMzY1MTM1OSwKCQkJMS4wMjI2NjAwNDksCgkJCTEuMDIxNjgzNDU4LAoJCQkxLjAyMDcyMTQ0NiwKCQkJMS4wMTk3NzM4NzMsCgkJCTEuMDE4ODQwNjA0LAoJCQkxLjAxNzkyMTUwMywKCQkJMS4wMTcwMTY0MzgsCgkJCTEuMDE2MTI1Mjc5LAoJCQkxLjAxNTI0Nzg5NywKCQkJMS4wMTQzODQxNjUsCgkJCTEuMDEzNTMzOTU4LAoJCQkxLjAxMjY5NzE1MywKCQkJMS4wMTE4NzM2MjksCgkJCTEuMDExMDYzMjY2LAoJCQkxLjAxMDI2NTk0NywKCQkJMS4wMDk0ODE1NTUsCgkJCTEuMDA4NzA5OTc1LAoJCQkxLjAwNzk1MTA5NiwKCQkJMS4wMDcyMDQ4MDUsCgkJCTEuMDA2NDcwOTkzLAoJCQkxLjAwNTc0OTU1MiwKCQkJMS4wMDUwNDAzNzYsCgkJCTEuMDA0MzQzMzU4LAoJCQkxLjAwMzY1ODM5NywKCQkJMS4wMDI5ODUzODksCgkJCTEuMDAyMzI0MjMzLAoJCQkxLjAwMTY3NDgzMSwKCQkJMS4wMDEwMzcwODUsCgkJCTEuMDAwNDEwODk3LAoJCQkwLjk5OTc5NjE3MywKCQkJMC45OTkxOTI4MTksCgkJCTAuOTk4NjAwNzQyLAoJCQkwLjk5ODAxOTg1MSwKCQkJMC45OTc0NTAwNTUsCgkJCTAuOTk2ODkxMjY2LAoJCQkwLjk5NjM0MzM5NiwKCQkJMC45OTU4MDYzNTgsCgkJCTAuOTk1MjgwMDY4LAoJCQkwLjk5NDc2NDQ0LAoJCQkwLjk5NDI1OTM5MywKCQkJMC45OTM3NjQ4NDQsCgkJCTAuOTkzMjgwNzExLAoJCQkwLjk5MjgwNjkxNywKCQkJMC45OTIzNDMzODEsCgkJCTAuOTkxODkwMDI2LAoJCQkwLjk5MTQ0Njc3NiwKCQkJMC45OTEwMTM1NTUsCgkJCTAuOTkwNTkwMjg5LAoJCQkwLjk5MDE3NjkwMywKCQkJMC45ODk3NzMzMjUsCgkJCTAuOTg5Mzc5NDg0LAoJCQkwLjk4ODk5NTMwOSwKCQkJMC45ODg2MjA3MjksCgkJCTAuOTg4MjU1Njc3LAoJCQkwLjk4NzkwMDA4MywKCQkJMC45ODc1NTM4ODIsCgkJCTAuOTg3MjE3MDA2LAoJCQkwLjk4Njg4OTM5LAoJCQkwLjk4NjU3MDk3LAoJCQkwLjk4NjI2MTY4MiwKCQkJMC45ODU5NjE0NjMsCgkJCTAuOTg1NjcwMjUxLAoJCQkwLjk4NTM4Nzk4NSwKCQkJMC45ODUxMTQ2MDQsCgkJCTAuOTg0ODUwMDQ4LAoJCQkwLjk4NDU5NDI1OSwKCQkJMC45ODQzNDcxNzgsCgkJCTAuOTg0MTA4NzQ4LAoJCQkwLjk4Mzg3ODkxMSwKCQkJMC45ODM2NTc2MTMsCgkJCTAuOTgzNDQ0Nzk3LAoJCQkwLjk4MzI0MDQwOSwKCQkJMC45ODMwNDQzOTQsCgkJCTAuOTgyODU2NzAxLAoJCQkwLjk4MjY3NzI3NiwKCQkJMC45ODI1MDYwNjYsCgkJCTAuOTgyMzQzMDIyLAoJCQkwLjk4MjE4ODA5MSwKCQkJMC45ODIwNDEyMjUsCgkJCTAuOTgxOTAyMzczLAoJCQkwLjk4MTc3MTQ4NywKCQkJMC45ODE2NDg1MTksCgkJCTAuOTgxNTMzNDIxLAoJCQkwLjk4MTQyNjE0NiwKCQkJMC45ODEzMjY2NDgsCgkJCTAuOTgxMjM0ODgsCgkJCTAuOTgxMTUwNzk4LAoJCQkwLjk4MTA3NDM1NiwKCQkJMC45ODEwMDU1MTEsCgkJCTAuOTgwOTQ0MjE5LAoJCQkwLjk4MDg5MDQzNywKCQkJMC45ODA4NDQxMjIsCgkJCTAuOTgwODA1MjMyLAoJCQkwLjk4MDc3MzcyNiwKCQkJMC45ODA3NDk1NjIsCgkJCTAuOTgwNzMyNywKCQkJMC45ODA3MjMxLAoJCQkwLjk4MDcyMDcyMiwKCQkJMC45ODA3MjU1MjgsCgkJCTAuOTgwNzM3NDc4LAoJCQkwLjk4MDc1NjUzNCwKCQkJMC45ODA3ODI2NiwKCQkJMC45ODA4MTU4MTcsCgkJCTAuOTgwODU1OTY4LAoJCQkwLjk4MDkwMzA3OSwKCQkJMC45ODA5NTU0NzUsCgkJCTAuOTgxMDE3OTQyLAoJCQkwLjk4MTA4NTcxNCwKCQkJMC45ODExNjAzMDMsCgkJCTAuOTgxMjQxNjc1LAoJCQkwLjk4MTMyOTc5NiwKCQkJMC45ODE0MjQ2MzQsCgkJCTAuOTgxNTI2MTU0LAoJCQkwLjk4MTYzNDMyNSwKCQkJMC45ODE3NDkxMTQsCgkJCTAuOTgxODcwNDg5LAoJCQkwLjk4MTk5ODQxOSwKCQkJMC45ODIxMzI4NzMsCgkJCTAuOTgyMjczODIsCgkJCTAuOTgyNDIxMjI5LAoJCQkwLjk4MjU3NTA3MiwKCQkJMC45ODI3MzUzMTgsCgkJCTAuOTgyOTAxOTM3LAoJCQkwLjk4MzA3NDkwMiwKCQkJMC45ODMyNTQxODMsCgkJCTAuOTgzNDM5NzUyLAoJCQkwLjk4MzYzMTU4MiwKCQkJMC45ODM4Mjk2NDQsCgkJCTAuOTg0MDMzOTEyLAoJCQkwLjk4NDI0NDM1OCwKCQkJMC45ODQ0NjA5NTYsCgkJCTAuOTg0NjgzNjgxLAoJCQkwLjk4NDkxMjUwNSwKCQkJMC45ODUxNDc0MDMsCgkJCTAuOTg1Mzg4MzQ5LAoJCQkwLjk4NTYzNTMyLAoJCQkwLjk4NTg4ODI5LAoJCQkwLjk4NjE0NzIzNCwKCQkJMC45ODY0MTIxMjgsCgkJCTAuOTg2NjgyOTQ5LAoJCQkwLjk4Njk1OTY3MywKCQkJMC45ODcyNDIyNzcsCgkJCTAuOTg3NTMwNzM3LAoJCQkwLjk4NzgyNTAzMSwKCQkJMC45ODgxMjUxMzYsCgkJCTAuOTg4NDMxMDMsCgkJCTAuOTg4NzQyNjkxLAoJCQkwLjk4OTA2MDA5OCwKCQkJMC45ODkzODMyMjksCgkJCTAuOTg5NzEyMDYzLAoJCQkwLjk5MDA0NjU3OSwKCQkJMC45OTAzODY3NTYsCgkJCTAuOTkwNzMyNTc0LAoJCQkwLjk5MTA4NDAxMiwKCQkJMC45OTE0NDEwNTIsCgkJCTAuOTkxODAzNjcyLAoJCQkwLjk5MjE3MTg1NCwKCQkJMC45OTI1NDU1NzgsCgkJCTAuOTkyOTI0ODI1LAoJCQkwLjk5MzMwOTU3OCwKCQkJMC45OTM2OTk4MTYsCgkJCTAuOTk0MDk1NTIyLAoJCQkwLjk5NDQ5NjY3NywKCQkJMC45OTQ5MDMyNjUsCgkJCTAuOTk1MzE1MjY2LAoJCQkwLjk5NTczMjY2NSwKCQkJMC45OTYxNTU0NDIsCgkJCTAuOTk2NTgzNTgyLAoJCQkwLjk5NzAxNzA2OCwKCQkJMC45OTc0NTU4ODMsCgkJCTAuOTk3OTAwMDEsCgkJCTAuOTk4MzQ5NDM0LAoJCQkwLjk5ODgwNDEzOCwKCQkJMC45OTkyNjQxMDcsCgkJCTAuOTk5NzI5MzI1LAoJCQkxLjAwMDE5OTc3NiwKCQkJMS4wMDA2NzU0NDYsCgkJCTEuMDAxMTU2MzE5LAoJCQkxLjAwMTY0MjM4MSwKCQkJMS4wMDIxMzM2MTcsCgkJCTEuMDAyNjMwMDExLAoJCQkxLjAwMzEzMTU1MSwKCQkJMS4wMDM2MzgyMjIsCgkJCTEuMDA0MTUwMDEsCgkJCTEuMDA0NjY2OTAxLAoJCQkxLjAwNTE4ODg4MSwKCQkJMS4wMDU3MTU5MzgsCgkJCTEuMDA2MjQ4MDU4LAoJCQkxLjAwNjc4NTIyNywKCQkJMS4wMDczMjc0MzQsCgkJCTEuMDA3ODc0NjY1LAoJCQkxLjAwODQyNjkwNywKCQkJMS4wMDg5ODQxNDksCgkJCTEuMDA5NTQ2Mzc3LAoJCQkxLjAxMDExMzU4MSwKCQkJMS4wMTA2ODU3NDcsCgkJCTEuMDExMjYyODY1LAoJCQkxLjAxMTg0NDkyMiwKCQkJMS4wMTI0MzE5MDcsCgkJCTEuMDEzMDIzODA4LAoJCQkxLjAxMzYyMDYxNSwKCQkJMS4wMTQyMjIzMTcsCgkJCTEuMDE0ODI4OTAyLAoJCQkxLjAxNTQ0MDM2LAoJCQkxLjAxNjA1NjY4MSwKCQkJMS4wMTY2Nzc4NTMsCgkJCTEuMDE3MzAzODY2LAoJCQkxLjAxNzkzNDcxMSwKCQkJMS4wMTg1NzAzNzgsCgkJCTEuMDE5MjEwODU1LAoJCQkxLjAxOTg1NjEzNSwKCQkJMS4wMjA1MDYyMDYsCgkJCTEuMDIxMTYxMDYsCgkJCTEuMDIxODIwNjg3LAoJCQkxLjAyMjQ4NTA3OCwKCQkJMS4wMjMxNTQyMjQsCgkJCTEuMDIzODI4MTE2LAoJCQkxLjAyNDUwNjc0NSwKCQkJMS4wMjUxOTAxMDMsCgkJCTEuMDI1ODc4MTgsCgkJCTEuMDI2NTcwOTY5LAoJCQkxLjAyNzI2ODQ2MSwKCQkJMS4wMjc5NzA2NDcsCgkJCTEuMDI4Njc3NTIsCgkJCTEuMDI5Mzg5MDcyLAoJCQkxLjAzMDExNDk3MywKCQkJMS4wMzA4MjYwODgsCgkJCTEuMDMxNTUxNjMsCgkJCTEuMDMyMjgxODE5LAoJCQkxLjAzMzAxNjY1LAoJCQkxLjAzMzc1NjExNCwKCQkJMS4wMzQ1MDAyMDQsCgkJCTEuMDM1MjQ4OTEzLAoJCQkxLjAzNjAwMjIzNSwKCQkJMS4wMzY3NjAxNjIsCgkJCTEuMDM3NTIyNjg4LAoJCQkxLjAzODI4OTgwNiwKCQkJMS4wMzkwNjE1MDksCgkJCTEuMDM5ODM3NzkyLAoJCQkxLjA0MDYxODY0OAoJCX07CgoJCXN0YXRpYyBkb3VibGUgRmFzdEV4cChkb3VibGUgeCkKCQl7CgkJCXZhciB0bXAgPSAobG9uZykoMTUxMjc3NSAqIHggKyAxMDcyNjMyNDQ3KTsKCQkJaW50IGluZGV4ID0gKGludCkodG1wID4+IDEyKSAmIDB4RkY7CgkJCXJldHVybiBCaXRDb252ZXJ0ZXIuSW50NjRCaXRzVG9Eb3VibGUodG1wIDw8IDMyKSAqIEV4cEFkanVzdG1lbnRbaW5kZXhdOwoJCX0KCgkJc3RhdGljIHZvaWQgTWFpbihzdHJpbmdbXSBhcmdzKQoJCXsKCQkJZG91YmxlW10geCA9IG5ldyBkb3VibGVbMTAwMDAwMF07CgkJCWRvdWJsZVtdIGV4ID0gbmV3IGRvdWJsZVt4Lkxlbmd0aF07CgkJCWRvdWJsZVtdIGZ4ID0gbmV3IGRvdWJsZVt4Lkxlbmd0aF07CgkJCVJhbmRvbSByID0gbmV3IFJhbmRvbSgpOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IHguTGVuZ3RoOyArK2kpCgkJCQl4W2ldID0gci5OZXh0RG91YmxlKCkgKiA0MDsKCgkJCVN0b3B3YXRjaCBzdyA9IG5ldyBTdG9wd2F0Y2goKTsKCQkJc3cuU3RhcnQoKTsKCQkJZm9yIChpbnQgaiA9IDA7IGogPCB4Lkxlbmd0aDsgKytqKQoJCQkJZXhbal0gPSBNYXRoLkV4cCh4W2pdKTsKCQkJc3cuU3RvcCgpOwoJCQlkb3VibGUgYnVpbHRpbiA9IHN3LkVsYXBzZWQuVG90YWxNaWxsaXNlY29uZHM7CgkJCXN3LlJlc2V0KCk7CgkJCXN3LlN0YXJ0KCk7CgkJCWZvciAoaW50IGsgPSAwOyBrIDwgeC5MZW5ndGg7ICsraykKCQkJCWZ4W2tdID0gRmFzdEV4cCh4W2tdKTsKCQkJc3cuU3RvcCgpOwoJCQlkb3VibGUgY3VzdG9tID0gc3cuRWxhcHNlZC5Ub3RhbE1pbGxpc2Vjb25kczsKCgkJCWRvdWJsZSBtaW4gPSAxLCBtYXggPSAxOwoJCQlmb3IgKGludCBtID0gMDsgbSA8IHguTGVuZ3RoOyArK20pIHsKCQkJCWRvdWJsZSByYXRpbyA9IGZ4W21dIC8gZXhbbV07CgkJCQlpZiAobWluID4gcmF0aW8pIG1pbiA9IHJhdGlvOwoJCQkJaWYgKG1heCA8IHJhdGlvKSBtYXggPSByYXRpbzsKCQkJfQoKCQkJQ29uc29sZS5Xcml0ZUxpbmUoIm1pbmltdW0gcmF0aW8gPSAiICsgbWluLlRvU3RyaW5nKCkgKyAiLCBtYXhpbXVtIHJhdGlvID0gIiArIG1heC5Ub1N0cmluZygpICsgIiwgc3BlZWR1cCA9ICIgKyAoYnVpbHRpbiAvIGN1c3RvbSkuVG9TdHJpbmcoKSk7CgkJIH0KCX0KfQo=