public static MultiPrecision <N> Pow2(MultiPrecision <N> x) { if (x.IsNaN) { return(NaN); } MultiPrecision <N> x_int = Floor(x); if (x_int.Exponent >= UIntUtil.UInt32Bits) { if (x.Sign == Sign.Plus) { return(PositiveInfinity); } else { return(Zero); } } Int64 exponent = x_int.mantissa.Value.Last() >> (UIntUtil.UInt32Bits - (int)x_int.Exponent - 1); if (x_int.Sign == Sign.Minus) { exponent = -exponent; } MultiPrecision <N> x_frac = x - x_int; MultiPrecision <N> v = Ln2 * x_frac; if (v.IsZero || v.Exponent < int.MinValue) { return(new MultiPrecision <N>(Sign.Plus, exponent, Mantissa <N> .One, round: false)); } Accumulator <N> a = Accumulator <N> .One, m = new(v.mantissa, (int)v.Exponent), w = m; foreach (var t in Accumulator <N> .TaylorTable) { Accumulator <N> d = w * t; if (d.Digits < Length) { break; } a += d; w = Accumulator <N> .RightRoundShift(w *m, Mantissa <N> .Bits - 1); } (Mantissa <N> n, int sft) = a.Mantissa; MultiPrecision <N> y = new(Sign.Plus, exponent - sft + 1, n, round : false); return(y); }
public static MultiPrecision <N> Log2(MultiPrecision <N> x) { if (!(x >= Zero)) { return(NaN); } if (x.IsZero) { return(NegativeInfinity); } if (x == PositiveInfinity) { return(PositiveInfinity); } if (x.mantissa == Mantissa <N> .One) { return(x.Exponent); } Accumulator <N> v = new(x.mantissa); int sft; for (sft = 0; sft < Accumulator <N> .Bits; sft++) { v *= v; if (v.Value[Accumulator <N> .Length - 1] > UIntUtil.UInt32Round) { v = Accumulator <N> .RightRoundBlockShift(v, Mantissa <N> .Length); break; } else { v = Accumulator <N> .RightRoundShift(v, Mantissa <N> .Bits - 1); } } if (sft == Accumulator <N> .Bits) { return(x.Exponent); } UInt32[] mantissa = new UInt32[Mantissa <N> .Length]; UInt32 m = 1; for (int i = mantissa.Length - 1; i >= 0; i--) { for (int j = (i < mantissa.Length - 1) ? 0 : 1; j < UIntUtil.UInt32Bits; j++) { v *= v; m <<= 1; if (v.Value[Accumulator <N> .Length - 1] > UIntUtil.UInt32Round) { v = Accumulator <N> .RightRoundBlockShift(v, Mantissa <N> .Length); m |= 1u; } else { v = Accumulator <N> .RightRoundShift(v, Mantissa <N> .Bits - 1); } } mantissa[i] = m; m = 0; } v *= v; bool round = v.Value[Accumulator <N> .Length - 1] > UIntUtil.UInt32Round; long intpart = x.Exponent; MultiPrecision <N> decpart = new(Sign.Plus, -(Int64)sft - 1, new Mantissa <N>(mantissa, enable_clone: false), round); MultiPrecision <N> y = intpart + decpart; return(y); }