### Question:
LogApproximator { public static FixedPoint log(BigInteger input) { if (null == input || input.compareTo(BigInteger.ONE) < 0) { throw new IllegalArgumentException("Invalid input to log approximator"); } else if (input.compareTo(BigInteger.ONE) == 0) { return FixedPoint.ZERO; } else { int bitLength = input.bitLength(); FixedPoint x = new FixedPoint(input.shiftLeft(FixedPoint.PRECISION - bitLength)); FixedPoint y = log2.multiplyInteger(bitLength); int leftShift = 1; while (leftShift < logTable.size() && x.compareTo(FixedPoint.ONE) <= 0) { FixedPoint xPrime = x.add(x.divideByPowerOfTwo(leftShift)); if (xPrime.compareTo(FixedPoint.ONE) <= 0) { x = xPrime; y = y.subtract(logTable.get(leftShift)); } else { leftShift++; } } y = y.add(x).subtract(FixedPoint.ONE); return y; } }  static FixedPoint log(BigInteger input);  }### Answer:
@Test public void testLog123456789() { Assert.assertEquals(Math.log(123456789), LogApproximator.log(new BigInteger("123456789")).toBigDecimal().doubleValue(), delta); }
@Ignore @Test public void testCollisions() { Set<FixedPoint> logs = new HashSet(); for (int i = 2; i < (1 << 20); i++) { FixedPoint log = LogApproximator.log(BigInteger.valueOf(i)); if (logs.contains(log)) { System.out.println("log of " + i + " is " + log + " which is already there"); } else { logs.add(log); } } }