BigIntegerMath.java 9.87 KB
package com.google.common.math;

import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import rg;
import rh;

@GwtCompatible(emulated=true)
public final class BigIntegerMath
{
  @VisibleForTesting
  static final BigInteger a = new BigInteger("16a09e667f3bcc908b2fb1366ea957d3e3adec17512775099da2f590b0667322a", 16);
  private static final double b = Math.log(10.0D);
  private static final double c = Math.log(2.0D);
  
  @GwtIncompatible("TODO")
  private static BigInteger a(BigInteger paramBigInteger)
  {
    int i = log2(paramBigInteger, RoundingMode.FLOOR);
    if (i < 1023) {}
    BigInteger localBigInteger2;
    BigInteger localBigInteger1;
    for (Object localObject = b(paramBigInteger);; localObject = b(paramBigInteger.shiftRight(i)).shiftLeft(i >> 1))
    {
      localBigInteger2 = ((BigInteger)localObject).add(paramBigInteger.divide((BigInteger)localObject)).shiftRight(1);
      localBigInteger1 = localBigInteger2;
      if (!((BigInteger)localObject).equals(localBigInteger2)) {
        break;
      }
      return (BigInteger)localObject;
      i = i - 52 & 0xFFFFFFFE;
    }
    do
    {
      localObject = localBigInteger1;
      localBigInteger2 = ((BigInteger)localObject).add(paramBigInteger.divide((BigInteger)localObject)).shiftRight(1);
      localBigInteger1 = localBigInteger2;
    } while (localBigInteger2.compareTo((BigInteger)localObject) < 0);
    return (BigInteger)localObject;
  }
  
  private static BigInteger a(List<BigInteger> paramList, int paramInt1, int paramInt2)
  {
    switch (paramInt2 - paramInt1)
    {
    default: 
      int i = paramInt2 + paramInt1 >>> 1;
      return a(paramList, paramInt1, i).multiply(a(paramList, i, paramInt2));
    case 0: 
      return BigInteger.ONE;
    case 1: 
      return (BigInteger)paramList.get(paramInt1);
    case 2: 
      return ((BigInteger)paramList.get(paramInt1)).multiply((BigInteger)paramList.get(paramInt1 + 1));
    }
    return ((BigInteger)paramList.get(paramInt1)).multiply((BigInteger)paramList.get(paramInt1 + 1)).multiply((BigInteger)paramList.get(paramInt1 + 2));
  }
  
  @GwtIncompatible("TODO")
  private static BigInteger b(BigInteger paramBigInteger)
  {
    return DoubleMath.roundToBigInteger(Math.sqrt(rg.a(paramBigInteger)), RoundingMode.HALF_EVEN);
  }
  
  public static BigInteger binomial(int paramInt1, int paramInt2)
  {
    rh.b("n", paramInt1);
    rh.b("k", paramInt2);
    if (paramInt2 <= paramInt1) {}
    int i;
    for (boolean bool = true;; bool = false)
    {
      Preconditions.checkArgument(bool, "k (%s) > n (%s)", new Object[] { Integer.valueOf(paramInt2), Integer.valueOf(paramInt1) });
      i = paramInt2;
      if (paramInt2 > paramInt1 >> 1) {
        i = paramInt1 - paramInt2;
      }
      if ((i >= LongMath.e.length) || (paramInt1 > LongMath.e[i])) {
        break;
      }
      return BigInteger.valueOf(LongMath.binomial(paramInt1, i));
    }
    BigInteger localBigInteger = BigInteger.ONE;
    long l1 = paramInt1;
    long l2 = 1L;
    int j = LongMath.log2(l1, RoundingMode.CEILING);
    int k = 1;
    paramInt2 = j;
    if (k < i)
    {
      int m = paramInt1 - k;
      int n = k + 1;
      if (paramInt2 + j >= 63)
      {
        localBigInteger = localBigInteger.multiply(BigInteger.valueOf(l1)).divide(BigInteger.valueOf(l2));
        l1 = m;
        l2 = n;
        paramInt2 = j;
      }
      for (;;)
      {
        k += 1;
        break;
        l1 *= m;
        l2 *= n;
        paramInt2 += j;
      }
    }
    return localBigInteger.multiply(BigInteger.valueOf(l1)).divide(BigInteger.valueOf(l2));
  }
  
  @GwtIncompatible("TODO")
  private static boolean c(BigInteger paramBigInteger)
  {
    return paramBigInteger.bitLength() <= 63;
  }
  
  @GwtIncompatible("TODO")
  public static BigInteger divide(BigInteger paramBigInteger1, BigInteger paramBigInteger2, RoundingMode paramRoundingMode)
  {
    return new BigDecimal(paramBigInteger1).divide(new BigDecimal(paramBigInteger2), 0, paramRoundingMode).toBigIntegerExact();
  }
  
  public static BigInteger factorial(int paramInt)
  {
    rh.b("n", paramInt);
    if (paramInt < LongMath.d.length) {
      return BigInteger.valueOf(LongMath.d[paramInt]);
    }
    ArrayList localArrayList = new ArrayList(IntMath.divide(IntMath.log2(paramInt, RoundingMode.CEILING) * paramInt, 64, RoundingMode.CEILING));
    int m = LongMath.d.length;
    long l1 = LongMath.d[(m - 1)];
    int j = Long.numberOfTrailingZeros(l1);
    l1 >>= j;
    int i = LongMath.log2(l1, RoundingMode.FLOOR);
    int k = LongMath.log2(m, RoundingMode.FLOOR) + 1;
    long l2 = m;
    int i1 = 1 << k - 1;
    i += 1;
    while (l2 <= paramInt)
    {
      int n = i1;
      m = k;
      if ((i1 & l2) != 0L)
      {
        n = i1 << 1;
        m = k + 1;
      }
      k = Long.numberOfTrailingZeros(l2);
      j += k;
      long l3 = l1;
      if (i + (m - k) >= 64)
      {
        localArrayList.add(BigInteger.valueOf(l1));
        l3 = 1L;
      }
      l1 = l3 * (l2 >> k);
      i = LongMath.log2(l1, RoundingMode.FLOOR) + 1;
      l2 = 1L + l2;
      i1 = n;
      k = m;
    }
    if (l1 > 1L) {
      localArrayList.add(BigInteger.valueOf(l1));
    }
    return a(localArrayList, 0, localArrayList.size()).shiftLeft(j);
  }
  
  public static boolean isPowerOfTwo(BigInteger paramBigInteger)
  {
    Preconditions.checkNotNull(paramBigInteger);
    return (paramBigInteger.signum() > 0) && (paramBigInteger.getLowestSetBit() == paramBigInteger.bitLength() - 1);
  }
  
  @GwtIncompatible("TODO")
  public static int log10(BigInteger paramBigInteger, RoundingMode paramRoundingMode)
  {
    rh.a("x", paramBigInteger);
    int k;
    if (c(paramBigInteger))
    {
      k = LongMath.log10(paramBigInteger.longValue(), paramRoundingMode);
      return k;
    }
    int j = (int)(log2(paramBigInteger, RoundingMode.FLOOR) * c / b);
    Object localObject = BigInteger.TEN.pow(j);
    int i = ((BigInteger)localObject).compareTo(paramBigInteger);
    BigInteger localBigInteger;
    if (i > 0)
    {
      do
      {
        i = j - 1;
        localBigInteger = ((BigInteger)localObject).divide(BigInteger.TEN);
        k = localBigInteger.compareTo(paramBigInteger);
        localObject = localBigInteger;
        j = i;
      } while (k > 0);
      j = k;
      localObject = localBigInteger;
      label105:
      k = i;
      switch (1.a[paramRoundingMode.ordinal()])
      {
      case 2: 
      case 3: 
      default: 
        throw new AssertionError();
      }
    }
    for (;;)
    {
      localBigInteger = BigInteger.TEN.multiply((BigInteger)localObject);
      k = localBigInteger.compareTo(paramBigInteger);
      if (k <= 0)
      {
        localObject = localBigInteger;
        j += 1;
        i = k;
        continue;
        if (j == 0) {}
        for (boolean bool = true;; bool = false)
        {
          rh.a(bool);
          return i;
        }
        k = i;
        if (((BigInteger)localObject).equals(paramBigInteger)) {
          break;
        }
        return i + 1;
        k = i;
        if (paramBigInteger.pow(2).compareTo(((BigInteger)localObject).pow(2).multiply(BigInteger.TEN)) <= 0) {
          break;
        }
        return i + 1;
      }
      k = j;
      j = i;
      i = k;
      break label105;
    }
  }
  
  public static int log2(BigInteger paramBigInteger, RoundingMode paramRoundingMode)
  {
    rh.a("x", (BigInteger)Preconditions.checkNotNull(paramBigInteger));
    int i = paramBigInteger.bitLength() - 1;
    switch (1.a[paramRoundingMode.ordinal()])
    {
    default: 
      throw new AssertionError();
    case 1: 
      rh.a(isPowerOfTwo(paramBigInteger));
    }
    do
    {
      do
      {
        do
        {
          return i;
        } while (isPowerOfTwo(paramBigInteger));
        return i + 1;
        if (i >= 256) {
          break;
        }
      } while (paramBigInteger.compareTo(a.shiftRight(256 - i)) <= 0);
      return i + 1;
    } while (paramBigInteger.pow(2).bitLength() - 1 < i * 2 + 1);
    return i + 1;
  }
  
  @GwtIncompatible("TODO")
  public static BigInteger sqrt(BigInteger paramBigInteger, RoundingMode paramRoundingMode)
  {
    if (paramBigInteger.signum() < 0)
    {
      paramRoundingMode = String.valueOf(String.valueOf("x"));
      paramBigInteger = String.valueOf(String.valueOf(paramBigInteger));
      throw new IllegalArgumentException(paramRoundingMode.length() + 16 + paramBigInteger.length() + paramRoundingMode + " (" + paramBigInteger + ") must be >= 0");
    }
    Object localObject;
    if (c(paramBigInteger)) {
      localObject = BigInteger.valueOf(LongMath.sqrt(paramBigInteger.longValue(), paramRoundingMode));
    }
    BigInteger localBigInteger;
    do
    {
      return (BigInteger)localObject;
      localBigInteger = a(paramBigInteger);
      localObject = localBigInteger;
      switch (1.a[paramRoundingMode.ordinal()])
      {
      case 2: 
      case 3: 
      default: 
        throw new AssertionError();
      case 1: 
        rh.a(localBigInteger.pow(2).equals(paramBigInteger));
        return localBigInteger;
      case 4: 
      case 5: 
        int i = localBigInteger.intValue();
        if ((i * i == paramBigInteger.intValue()) && (localBigInteger.pow(2).equals(paramBigInteger))) {}
        for (i = 1;; i = 0)
        {
          localObject = localBigInteger;
          if (i != 0) {
            break;
          }
          return localBigInteger.add(BigInteger.ONE);
        }
      }
      localObject = localBigInteger;
    } while (localBigInteger.pow(2).add(localBigInteger).compareTo(paramBigInteger) >= 0);
    return localBigInteger.add(BigInteger.ONE);
  }
}


/* Location:              /home/merong/decompile/hackery-dex2jar.jar!/com/google/common/math/BigIntegerMath.class
 * Java compiler version: 6 (50.0)
 * JD-Core Version:       0.7.1
 */