Several power function calculation methods and Power Function Methods

Source: Internet
Author: User
Tags natural logarithm arch linux

Several power function calculation methods and Power Function Methods
Introduction

We know that the Base e of the natural logarithm is defined as the following limit value:

This formula is suitable for some tests on power function calculation. The result is an approximate value of e, so you don't have to worry that the calculation result will overflow when n is large.

Test procedure

Here is Tester. cs:

 1 using System; 2 using System.Numerics; 3 using System.Diagnostics; 4 using Skyiv.Extensions; 5  6 namespace Skyiv.Test 7 { 8   sealed class Tester 9   {10     string Standard(long n)11     { // n == 10^m12       if (n > 100000) return "Skip";13       var s = BigInteger.Pow(n + 1, (int)n).ToString();14       s = s.Substring(0, Math.Min(31, s.Length));15       return s[0] + "." + s.Substring(1);16     }17     18     string Direct(long n)19     {20       if (n > 1000000000) return "Skip";21       var y = 1m;22       for (var x = 1 + 1m / n; n > 0; n--) y *= x;23       return y.ToString();24     }25     26     string Binary(long n)27     {28       var y = 1m;29       for (var x = 1 + 1m / n; n != 0; x *= x, n >>= 1)30         if ((n & 1) != 0) y *= x;31       return y.ToString();32     }33     34     string ExpLog(long n)35     {36       return (1 + 1m / n).Pow(n).ToString();37     }38     39     void Out(string name, Func<long, string> func, long n)40     {41       var timer = Stopwatch.StartNew();42       var y = func(n);43       timer.Stop();44       Console.WriteLine("{0,-32} {1} {2}", y, timer.Elapsed, name);45     }46     47     void Run(int max)48     {49       for (var m = 0; m <= max; m++)50       {51         var n = (long)Math.Pow(10, m);52         Console.WriteLine(string.Format("- {0:D2}:{1:N0} ", m, n).PadRight(58, '-'));53         Out("Standard", Standard, n);54         Out("Direct", Direct, n);55         Out("Binary", Binary, n);56         Out("ExpLog", ExpLog, n);57       }58     }59   60     static void Main()61     {62       new Tester().Run(18);63     }64   }65 }

This program uses four methods to calculate the power function:

  1. The Standard method of rows 10th to 16 uses the BigInteger. Pow method to calculate the power function. This calculation result (within the valid number range) is an accurate value and serves as a standard for other methods.
  2. The Direct method from 18th to 24 rows directly multiplied x n times to calculate the power function, which is the least technically violent method. The time complexity is O (N ).
  3. The Binary method of rows 26th to 32 considers n as the Binary number and calculates the power function based on its 1 bit. This is a classic algorithm, and the time complexity is O (logN ). The BigInteger. Pow method of FCL also uses this algorithm.
  4. The ExpLog method of rows 34th to 37 uses the decimal Extension Method Pow to calculate the power function, which is calculated by the logarithm function and the exponential function :. In theory, the time complexity is O (1 ).
Decimal Extension Method

The following is DecimalExtensions. cs:

 1 using System; 2  3 namespace Skyiv.Extensions 4 { 5   static class DecimalExtensions 6   { 7     static readonly int[] mask = { 1, 2, 4, 8, 16, 32, 64 }; 8     static readonly decimal ln10 = 2.3025850929940456840179914547m; 9     static readonly decimal lnr = 0.2002433314278771112016301167m;10     static readonly decimal expmax = 66.542129333754749704054283659m;11     static readonly decimal[] exps =12     {13       2.71828182845904523536028747135m, // exp(1)14       7.38905609893065022723042746058m, // exp(2)15       54.5981500331442390781102612029m, // exp(4)16       2980.95798704172827474359209945m, // exp(8)17       8886110.52050787263676302374078m, // exp(16)18       78962960182680.6951609780226351m, // exp(32)19       6235149080811616882909238708.93m  // exp(64)20     };21 22     public static decimal Log10(this decimal x)23     {24       return Log(x) / ln10;25     }26 27     public static decimal Log(this decimal x)28     {29       if (x <= 0) throw new ArgumentException("Must be positive");30       int k = 0, l = 0;31       for (; x >= 1.10527199m; k++) x /= 10;32       for (; x <= 0.1m; k--) x *= 10;        // ( 0.1000, 1.10527199 )33       for (; x < 0.9047m; l--) x *= 1.2217m; // [ 0.9047, 1.10527199 )34       return k * ln10 + l * lnr + Logarithm((x - 1) / (x + 1));35     }36     37     static decimal Logarithm(decimal y)38     { // y in ( -0.05-, 0.05+ ), return ln((1+y)/(1-y))39       decimal v = 1, y2 = y * y, t = y2, z = t / 3;40       for (var i = 3; z != 0; z = (t *= y2) / (i += 2)) v += z;41       return v * y * 2;42     }43     44     public static decimal Exp(this decimal x)45     {46       if (x > expmax) throw new OverflowException("overflow");47       if (x < -66) return 0;48       var n = (int)decimal.Round(x);49       if (n > 66) n--;50       decimal z = 1, y = Exponential(x - n);51       for (int m = (n < 0) ? -n : n, i = 0; i < mask.Length; i++)52         if ((m & mask[i]) != 0) z *= exps[i];53       return (n < 0) ? (y / z) : (y * z);54     }55     56     static decimal Exponential(decimal q)57     { // q (almost) in [ -0.5, 0.5 ]58       decimal y = 1, t = q;59       for (var i = 1; t != 0; t *= q / ++i) y += t;60       return y;61     }62     63     public static decimal Pow(this decimal x, decimal y)64     {65       if (x == 0 && y > 0) return 0;66       if (y == 0 && x != 0) return 1;67       return Exp(y * Log(x));68     }69   }70 }

For more information about this procedure, see [5] and [6].

Compile and run

Compile and run in the Mono environment of the Arch Linux operating system:

work$ dmcs -r:System.Numerics.dll Tester.cs DecimalExtensions.cswork$ mono Tester.exe- 00:1 ---------------------------------------------------2.                               00:00:00.0085818 Standard2                                00:00:00.0033230 Direct2                                00:00:00.0002739 Binary2.0000000000000000000000000005   00:00:00.0049157 ExpLog- 01:10 --------------------------------------------------2.5937424601                     00:00:00.0015421 Standard2.5937424601000000000000000000   00:00:00.0000146 Direct2.5937424601000000000000000000   00:00:00.0000092 Binary2.5937424600999999999999999977   00:00:00.0000488 ExpLog- 02:100 -------------------------------------------------2.704813829421526093267194710807 00:00:00.0006872 Standard2.7048138294215260932671947112   00:00:00.0000735 Direct2.7048138294215260932671947103   00:00:00.0000234 Binary2.7048138294215260932671947257   00:00:00.0000330 ExpLog- 03:1,000 -----------------------------------------------2.716923932235892457383088121947 00:00:00.0277308 Standard2.7169239322358924573830881229   00:00:00.0007167 Direct2.7169239322358924573830881218   00:00:00.0000159 Binary2.7169239322358924573830883380   00:00:00.0000310 ExpLog- 04:10,000 ----------------------------------------------2.718145926825224864037664674913 00:00:03.3247007 Standard2.7181459268252248640376646760   00:00:00.0068304 Direct2.7181459268252248640376646665   00:00:00.0000191 Binary2.7181459268252248640376679109   00:00:00.0000276 ExpLog- 05:100,000 ---------------------------------------------2.718268237174489668035064824426 00:07:56.2341075 Standard2.7182682371744896680350648397   00:00:00.0686007 Direct2.7182682371744896680350643783   00:00:00.0000222 Binary2.7182682371744896680350286262   00:00:00.0000255 ExpLog- 06:1,000,000 -------------------------------------------Skip                             00:00:00.0000008 Standard2.7182804693193768838197997202   00:00:00.6837104 Direct2.7182804693193768838198166432   00:00:00.0000241 Binary2.7182804693193768838199803836   00:00:00.0000213 ExpLog- 07:10,000,000 ------------------------------------------Skip                             00:00:00.0000009 Standard2.7182816925449662711985502083   00:00:06.8334721 Direct2.7182816925449662711985623547   00:00:00.0000289 Binary2.7182816925449662712010419841   00:00:00.0000221 ExpLog- 08:100,000,000 -----------------------------------------Skip                             00:00:00.0000009 Standard2.7182818148676362176529774118   00:01:08.3492423 Direct2.7182818148676362176523859621   00:00:00.0000409 Binary2.7182818148676362176710998015   00:00:00.0000230 ExpLog- 09:1,000,000,000 ---------------------------------------Skip                             00:00:00.0000007 Standard2.7182818270999043223766453801   00:11:23.4187574 Direct2.7182818270999043223770801045   00:00:00.0000442 Binary2.7182818270999043220142064477   00:00:00.0000215 ExpLog- 10:10,000,000,000 --------------------------------------Skip                             00:00:00.0000007 StandardSkip                             00:00:00.0000008 Direct2.7182818283231311436196542093   00:00:00.0000349 Binary2.7182818283231311439407330619   00:00:00.0000172 ExpLog- 11:100,000,000,000 -------------------------------------Skip                             00:00:00.0000008 StandardSkip                             00:00:00.0000010 Direct2.7182818284454538261539965115   00:00:00.0000398 Binary2.7182818284454538262180262237   00:00:00.0000176 ExpLog- 12:1,000,000,000,000 -----------------------------------Skip                             00:00:00.0000010 StandardSkip                             00:00:00.0000007 Direct2.7182818284576860942863185484   00:00:00.0000403 Binary2.7182818284576860944460582886   00:00:00.0000174 ExpLog- 13:10,000,000,000,000 ----------------------------------Skip                             00:00:00.0000009 StandardSkip                             00:00:00.0000007 Direct2.7182818284589093212295138270   00:00:00.0000436 Binary2.7182818284589093212688645227   00:00:00.0000176 ExpLog- 14:100,000,000,000,000 ---------------------------------Skip                             00:00:00.0000009 StandardSkip                             00:00:00.0000009 Direct2.7182818284590316438350187680   00:00:00.0000480 Binary2.7182818284590452353602874714   00:00:00.0000112 ExpLog- 15:1,000,000,000,000,000 -------------------------------Skip                             00:00:00.0000009 StandardSkip                             00:00:00.0000009 Direct2.7182818284590431765145511000   00:00:00.0000522 Binary2.7182818284590452353602874714   00:00:00.0000114 ExpLog- 16:10,000,000,000,000,000 ------------------------------Skip                             00:00:00.0000009 StandardSkip                             00:00:00.0000006 Direct2.7182818284590335325626228124   00:00:00.0000547 Binary2.7182818284590452353602874714   00:00:00.0000109 ExpLog- 17:100,000,000,000,000,000 -----------------------------Skip                             00:00:00.0000010 StandardSkip                             00:00:00.0000006 Direct2.7182818284590296936415060358   00:00:00.0000567 Binary2.7182818284590452353602874714   00:00:00.0000108 ExpLog- 18:1,000,000,000,000,000,000 ---------------------------Skip                             00:00:00.0000010 StandardSkip                             00:00:00.0000006 Direct2.7182818284590434884535909399   00:00:00.0000615 Binary2.7182818284590452353602874714   00:00:00.0000108 ExpLogwork$ echo 'scale=30;e(1)' | bc -lq2.718281828459045235360287471352

In the above results:

  1. The last line is the approximate value of e, which is calculated using the high-precision calculator bc of the Linux operating system. For details, see [4].
  2. BigInteger. Pow is used to calculate the exact value. In the, 000 group, the calculation result is 500,001 decimal digits. When n reaches 106, the exact value cannot be calculated within a reasonable period of time due to the large amount of computing.
  3. Using Direct is the slowest (except Standard, because the calculation workload is different ). When n reaches 1010, the Direct method is no longer used for calculation because it takes too much time.
  4. Binary computing is very fast, and its accuracy is similar to that of Direct. Different answers indicate that the multiplication of decimal does not meet the combination law.
  5. Using ExpLog computing is theoretically the fastest, and the actual speed is similar to that of ExpLog, because n is not large enough. The precision is slightly less accurate than n.
  6. When n reaches 1014, the calculated value of ExpLog is equal to the value of e in the range of 29 valid numbers.
  7. After n reaches 1014, due to the accumulation of rounding errors, only 14 valid numbers calculated by Binary are credible, and increasing the n value cannot be closer to the e value. That is to say, in the sense of approaching the e value, the calculation result does not change in the valid number range.
  8. The power function to be calculated is an addition function. Observe how the above running results reflect this.

Copyright statement: This article is the original author of the http://www.zuiniusn.com, not allowed by the blogger can not be reproduced.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.