Advertisement
jeff1203

Fib2

May 22nd, 2011
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.19 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3.  
  4. using BigInt = System.Numerics.BigInteger;
  5.  
  6. namespace FibTest
  7. {
  8.     class Program
  9.     {
  10.         static void Main(string[] args)
  11.         {
  12.             //Test1();
  13.             Test2();
  14.         }
  15.  
  16.         static void Test1()
  17.         {
  18.             for (int n = 0; n < 356; n++)
  19.             {
  20.                 var f = Fib(n);
  21.                 var db = Fib_b(n) - f;
  22.                 var dx = Fib_x(n) - f;
  23.  
  24.                 Console.WriteLine("{0,3}: {1}", n, f);
  25.                 Console.WriteLine(" db: {0:+0}", db);
  26.                 Console.WriteLine(" dx: {0:+0}", dx);
  27.                 Console.WriteLine();
  28.             }
  29.         }
  30.  
  31.         static void Test2()
  32.         {
  33.             var iterations = int.MaxValue;
  34.             var ib = 0;
  35.             var ix = 0;
  36.             int n;
  37.             for (n = 0; n < iterations; n++)
  38.             {
  39.                 try
  40.                 {
  41.                     var f = Fib(n);
  42.                     var b = Fib_b(n);
  43.                     var x = Fib_x(n);
  44.                     if (f != b) ib++;
  45.                     if (f != x) ix++;
  46.                 }
  47.                 catch (OverflowException)
  48.                 {
  49.                     // FP fail
  50.                     break;
  51.                 }
  52.             }
  53.  
  54.             Console.WriteLine("After {0} iterations, total inaccuracies found:", n);
  55.             Console.WriteLine("\tFib_b: {0}", ib);
  56.             Console.WriteLine("\tFib_x: {0}", ix);
  57.         }
  58.  
  59.         static readonly Dictionary<int, BigInt> memo = new Dictionary<int, BigInt>();
  60.         static BigInt Fib(int n)
  61.         {
  62.             BigInt result;
  63.             if (!memo.TryGetValue(n, out result))
  64.             {
  65.                 if (n < 2)
  66.                     memo[n] = result = BigInt.Max(0, n);
  67.                 else
  68.                     memo[n] = result = Fib(n - 1) + Fib(n - 2);
  69.             }
  70.             return result;
  71.         }
  72.  
  73.         static readonly double RAD5 = Math.Sqrt(5);
  74.         static readonly double PHI = (1 + RAD5) / 2;
  75.         static BigInt Fib_b(int n)
  76.         {
  77.             double result = Math.Pow(PHI, n) / RAD5;
  78.             return (BigInt)Math.Round(result);
  79.         }
  80.  
  81.         struct Complicated
  82.         {
  83.             private BigInt real;
  84.             private BigInt bogus;
  85.  
  86.             public Complicated(BigInt real, BigInt bogus)
  87.             {
  88.                 this.real = real;
  89.                 this.bogus = bogus;
  90.             }
  91.             public BigInt Real { get { return real; } }
  92.             public BigInt Bogus { get { return bogus; } }
  93.  
  94.             public static Complicated Pow(Complicated value, int exponent)
  95.             {
  96.                 if (exponent < 0)
  97.                     throw new ArgumentException("only non-negative exponents supported", "exponent");
  98.  
  99.                 Complicated result = 1;
  100.                 Complicated factor = value;
  101.                 for (int mask = exponent; mask != 0; mask >>= 1)
  102.                 {
  103.                     if ((mask & 0x1) != 0)
  104.                         result *= factor;
  105.                     factor *= factor;
  106.                 }
  107.                 return result;
  108.             }
  109.  
  110.             public static implicit operator Complicated(int real)
  111.             {
  112.                 return new Complicated(real, 0);
  113.             }
  114.  
  115.             public static Complicated operator -(Complicated l, Complicated r)
  116.             {
  117.                 var real = l.real - r.real;
  118.                 var bogus = l.bogus - r.bogus;
  119.                 return new Complicated(real, bogus);
  120.             }
  121.  
  122.             public static Complicated operator *(Complicated l, Complicated r)
  123.             {
  124.                 var real = l.real * r.real + 5 * l.bogus * r.bogus;
  125.                 var bogus = l.real * r.bogus + l.bogus * r.real;
  126.                 return new Complicated(real, bogus);
  127.             }
  128.         }
  129.  
  130.         static readonly Complicated TWO_PHI = new Complicated(1, 1);
  131.         static BigInt Fib_x(int n)
  132.         {
  133.             var x = Complicated.Pow(TWO_PHI, n) - Complicated.Pow(2 - TWO_PHI, n);
  134.             System.Diagnostics.Debug.Assert(x.Real == 0);
  135.             return x.Bogus / BigInt.Pow(2, n);
  136.         }
  137.     }
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement