@GwtIncompatible // TODO
  @SuppressWarnings("fallthrough")
  public static int log10(BigInteger x, RoundingMode mode) {
    checkPositive("x", x);
    if (fitsInLong(x)) {
      return LongMath.log10(x.longValue(), mode);
    }

    int approxLog10 = (int) (log2(x, FLOOR) * LN_2 / LN_10);
    BigInteger approxPow = BigInteger.TEN.pow(approxLog10);
    int approxCmp = approxPow.compareTo(x);

    /*
     * We adjust approxLog10 and approxPow until they're equal to floor(log10(x)) and
     * 10^floor(log10(x)).
     */

    if (approxCmp > 0) {
      /*
       * The code is written so that even completely incorrect approximations will still yield the
       * correct answer eventually, but in practice this branch should almost never be entered, and
       * even then the loop should not run more than once.
       */
      do {
        approxLog10--;
        approxPow = approxPow.divide(BigInteger.TEN);
        approxCmp = approxPow.compareTo(x);
      } while (approxCmp > 0);
    } else {
      BigInteger nextPow = BigInteger.TEN.multiply(approxPow);
      int nextCmp = nextPow.compareTo(x);
      while (nextCmp <= 0) {
        approxLog10++;
        approxPow = nextPow;
        approxCmp = nextCmp;
        nextPow = BigInteger.TEN.multiply(approxPow);
        nextCmp = nextPow.compareTo(x);
      }
    }

    int floorLog = approxLog10;
    BigInteger floorPow = approxPow;
    int floorCmp = approxCmp;

    switch (mode) {
      case UNNECESSARY:
        checkRoundingUnnecessary(floorCmp == 0);
        // fall through
      case FLOOR:
      case DOWN:
        return floorLog;

      case CEILING:
      case UP:
        return floorPow.equals(x) ? floorLog : floorLog + 1;

      case HALF_DOWN:
      case HALF_UP:
      case HALF_EVEN:
        // Since sqrt(10) is irrational, log10(x) - floorLog can never be exactly 0.5
        BigInteger x2 = x.pow(2);
        BigInteger halfPowerSquared = floorPow.pow(2).multiply(BigInteger.TEN);
        return (x2.compareTo(halfPowerSquared) <= 0) ? floorLog : floorLog + 1;
      default:
        throw new AssertionError();
    }
  }
@GwtIncompatible 
  @SuppressWarnings("fallthrough")
  public static int log10(BigInteger x, RoundingMode mode) {
    checkPositive("x", x);
    if (fitsInLong(x)) {
      return LongMath.log10(x.longValue(), mode);
    }

    int approxLog10 = (int) (log2(x, FLOOR) * LN_2 / LN_10);
    BigInteger approxPow = BigInteger.TEN.pow(approxLog10);
    int approxCmp = approxPow.compareTo(x);

    

    if (approxCmp > 0) {
      
      do {
        approxLog10--;
        approxPow = approxPow.divide(BigInteger.TEN);
        approxCmp = approxPow.compareTo(x);
      } while (approxCmp > 0);
    } else {
      BigInteger nextPow = BigInteger.TEN.multiply(approxPow);
      int nextCmp = nextPow.compareTo(x);
      while (nextCmp <= 0) {
        approxLog10++;
        approxPow = nextPow;
        approxCmp = nextCmp;
        nextPow = BigInteger.TEN.multiply(approxPow);
        nextCmp = nextPow.compareTo(x);
      }
    }

    int floorLog = approxLog10;
    BigInteger floorPow = approxPow;
    int floorCmp = approxCmp;

    switch (mode) {
      case UNNECESSARY:
        checkRoundingUnnecessary(floorCmp == 0);
        
      case FLOOR:
      case DOWN:
        return floorLog;

      case CEILING:
      case UP:
        return floorPow.equals(x) ? floorLog : floorLog + 1;

      case HALF_DOWN:
      case HALF_UP:
      case HALF_EVEN:
        
        BigInteger x2 = x.pow(2);
        BigInteger halfPowerSquared = floorPow.pow(2).multiply(BigInteger.TEN);
        return (x2.compareTo(halfPowerSquared) <= 0) ? floorLog : floorLog + 1;
      default:
        throw new AssertionError();
    }
  }
@ GwtIncompatible // TODO @ SuppressWarnings ( "fallthrough" ) public static int log10 ( BigInteger x , RoundingMode mode ) { checkPositive ( "x" , x ) ; if ( fitsInLong ( x ) ) { return LongMath . log10 ( x . longValue ( ) , mode ) ; } int approxLog10 = ( int ) ( log2 ( x , FLOOR ) * LN_2 / LN_10 ) ; BigInteger approxPow = BigInteger . TEN . pow ( approxLog10 ) ; int approxCmp = approxPow . compareTo ( x ) ; /*
     * We adjust approxLog10 and approxPow until they're equal to floor(log10(x)) and
     * 10^floor(log10(x)).
     */ if ( approxCmp > 0 ) { /*
       * The code is written so that even completely incorrect approximations will still yield the
       * correct answer eventually, but in practice this branch should almost never be entered, and
       * even then the loop should not run more than once.
       */ do { approxLog10 -- ; approxPow = approxPow . divide ( BigInteger . TEN ) ; approxCmp = approxPow . compareTo ( x ) ; } while ( approxCmp > 0 ) ; } else { BigInteger nextPow = BigInteger . TEN . multiply ( approxPow ) ; int nextCmp = nextPow . compareTo ( x ) ; while ( nextCmp <= 0 ) { approxLog10 ++ ; approxPow = nextPow ; approxCmp = nextCmp ; nextPow = BigInteger . TEN . multiply ( approxPow ) ; nextCmp = nextPow . compareTo ( x ) ; } } int floorLog = approxLog10 ; BigInteger floorPow = approxPow ; int floorCmp = approxCmp ; switch ( mode ) { case UNNECESSARY : checkRoundingUnnecessary ( floorCmp == 0 ) ; // fall through case FLOOR : case DOWN : return floorLog ; case CEILING : case UP : return floorPow . equals ( x ) ? floorLog : floorLog + 1 ; case HALF_DOWN : case HALF_UP : case HALF_EVEN : // Since sqrt(10) is irrational, log10(x) - floorLog can never be exactly 0.5 BigInteger x2 = x . pow ( 2 ) ; BigInteger halfPowerSquared = floorPow . pow ( 2 ) . multiply ( BigInteger . TEN ) ; return ( x2 . compareTo ( halfPowerSquared ) <= 0 ) ? floorLog : floorLog + 1 ; default : throw new AssertionError ( ) ; } }
Returns the base-10 logarithm of {@code x}, rounded according to the specified rounding mode.

@throws IllegalArgumentException if {@code x <= 0}
@throws ArithmeticException if {@code mode} is {@link RoundingMode#UNNECESSARY} and {@code x}
is not a power of ten
Returns the base - 10 logarithm of { @code x } rounded according to the specified rounding mode .