using System;
using System.Diagnostics;
namespace fastexponent
{
class Program
{
static double FastExp(double x)
{
var tmp = (long)(1512775 * x + 1072632447);
return BitConverter.Int64BitsToDouble(tmp << 32);
}
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());
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uRGlhZ25vc3RpY3M7CgpuYW1lc3BhY2UgZmFzdGV4cG9uZW50CnsKCWNsYXNzIFByb2dyYW0KCXsKCQlzdGF0aWMgZG91YmxlIEZhc3RFeHAoZG91YmxlIHgpCgkJewoJCQl2YXIgdG1wID0gKGxvbmcpKDE1MTI3NzUgKiB4ICsgMTA3MjYzMjQ0Nyk7CgkJCXJldHVybiBCaXRDb252ZXJ0ZXIuSW50NjRCaXRzVG9Eb3VibGUodG1wIDw8IDMyKTsKCQl9CgoJCXN0YXRpYyB2b2lkIE1haW4oc3RyaW5nW10gYXJncykKCQl7CgkJCWRvdWJsZVtdIHggPSBuZXcgZG91YmxlWzEwMDAwMDBdOwoJCQlkb3VibGVbXSBleCA9IG5ldyBkb3VibGVbeC5MZW5ndGhdOwoJCQlkb3VibGVbXSBmeCA9IG5ldyBkb3VibGVbeC5MZW5ndGhdOwoJCQlSYW5kb20gciA9IG5ldyBSYW5kb20oKTsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCB4Lkxlbmd0aDsgKytpKQoJCQkJeFtpXSA9IHIuTmV4dERvdWJsZSgpICogNDA7CgoJCQlTdG9wd2F0Y2ggc3cgPSBuZXcgU3RvcHdhdGNoKCk7CgkJCXN3LlN0YXJ0KCk7CgkJCWZvciAoaW50IGogPSAwOyBqIDwgeC5MZW5ndGg7ICsraikKCQkJCWV4W2pdID0gTWF0aC5FeHAoeFtqXSk7CgkJCXN3LlN0b3AoKTsKCQkJZG91YmxlIGJ1aWx0aW4gPSBzdy5FbGFwc2VkLlRvdGFsTWlsbGlzZWNvbmRzOwoJCQlzdy5SZXNldCgpOwoJCQlzdy5TdGFydCgpOwoJCQlmb3IgKGludCBrID0gMDsgayA8IHguTGVuZ3RoOyArK2spCgkJCQlmeFtrXSA9IEZhc3RFeHAoeFtrXSk7CgkJCXN3LlN0b3AoKTsKCQkJZG91YmxlIGN1c3RvbSA9IHN3LkVsYXBzZWQuVG90YWxNaWxsaXNlY29uZHM7CgoJCQlkb3VibGUgbWluID0gMSwgbWF4ID0gMTsKCQkJZm9yIChpbnQgbSA9IDA7IG0gPCB4Lkxlbmd0aDsgKyttKSB7CgkJCQlkb3VibGUgcmF0aW8gPSBmeFttXSAvIGV4W21dOwoJCQkJaWYgKG1pbiA+IHJhdGlvKSBtaW4gPSByYXRpbzsKCQkJCWlmIChtYXggPCByYXRpbykgbWF4ID0gcmF0aW87CgkJCX0KCgkJCUNvbnNvbGUuV3JpdGVMaW5lKCJtaW5pbXVtIHJhdGlvID0gIiArIG1pbi5Ub1N0cmluZygpICsgIiwgbWF4aW11bSByYXRpbyA9ICIgKyBtYXguVG9TdHJpbmcoKSArICIsIHNwZWVkdXAgPSAiICsgKGJ1aWx0aW4gLyBjdXN0b20pLlRvU3RyaW5nKCkpOwoJCSB9Cgl9Cn0K