/// <summary> /// Returns 2 raised to the specified power. /// </summary> public static Fix32 Pow2(this Fix32 xx) { #if USE_DOUBLES return(Math.Pow(2, x.ToDouble()).ToFix32()); #endif Fix32 x = xx; if ((int)x == 0) { return(Fix32.One); } // Avoid negative arguments by exploiting that exp(-x) = 1/exp(x). bool neg = (int)x < 0; if (neg) { x = x.Neg(); } if ((int)x == (int)Fix32.One) { return(neg ? Fix32.One.Div(Fix32.Two) : Fix32.Two); // Can be cached } if ((int)x >= (int)Fix32.Log2Max) { return(neg ? Fix32.One.Div(Fix32.MaxValue) : Fix32.MaxValue); // Can be cached } if ((int)x <= (int)Fix32.Log2Min) { return(neg ? Fix32.MaxValue : Fix32.Zero); } /* * The algorithm is based on the power series for exp(x): * http://en.wikipedia.org/wiki/Exponential_function#Formal_definition * * From term n, we get term n+1 by multiplying with x/n. * When the sum term drops to zero, we can stop summing. */ int integerPart = x.Floor().ToInt(); // Take fractional part of exponent x = (Fix32)((uint)x & FRACTIONAL_MASK); Fix32 result = Fix32.One; Fix32 term = Fix32.One; Fix32 i = Fix32.One; while ((int)term != 0) { term = x.Mul(term).Mul(Fix32.Ln2.Div(i)); result = result.Add(term); i = i.AddFast(Fix32.One); } result = (Fix32)((int)result << integerPart); if (neg) { result = Fix32.One.Div(result); } return(result); }