@Override
 public KademliaOverlayID getOverlayID(SkyNetID skyNetID) {
   BigDecimal dec = skyNetID.getID().multiply(upperBound);
   BigInteger kademliaOverlayID = null;
   try {
     kademliaOverlayID = dec.toBigIntegerExact();
   } catch (Exception e) {
     log.fatal("Unable to create exact integer out of " + dec.toPlainString());
   }
   return new KademliaOverlayID(kademliaOverlayID.subtract(BigInteger.ONE), config);
 }
 private static BigInteger convertBigDecimalToBigInteger(BigDecimal d)
     throws NumberFormatException {
   try {
     return d.toBigIntegerExact();
   } catch (ArithmeticException e) {
     NumberFormatException nfe =
         new NumberFormatException("Cannot represent BigDecimal " + d + " as BigInteger");
     nfe.initCause(e);
     throw nfe;
   }
 }
 private Object handlePrimitive(JsonPrimitive json) {
   if (json.isBoolean()) return json.getAsBoolean();
   else if (json.isString()) return json.getAsString();
   else {
     BigDecimal bigDec = json.getAsBigDecimal();
     // Find out if it is an int type
     try {
       bigDec.toBigIntegerExact();
       try {
         return bigDec.intValueExact();
       } catch (ArithmeticException e) {
       }
       return bigDec.longValue();
     } catch (ArithmeticException e) {
     }
     // Just return it as a double
     return bigDec.doubleValue();
   }
 }
  /**
   * Converts a {@link BigDecimal} value into the requested return type if possible.
   *
   * @param value the value
   * @param returnType the class of the returned value; it must be one of {@link BigDecimal}, {@link
   *     Double}, {@link Float}, {@link BigInteger}, {@link Long}, {@link Integer}, {@link Short},
   *     or {@link Byte}
   * @return the converted value
   * @throws IllegalArgumentException if the conversion is not possible or would lead to loss of
   *     data
   * @throws ClassCastException if the return type is not allowed
   */
  protected static <T> T convertDecimal(final BigDecimal value, final Class<T> returnType)
      throws IllegalArgumentException, ClassCastException {

    if (returnType.isAssignableFrom(BigDecimal.class)) {
      return returnType.cast(value);
    } else if (returnType.isAssignableFrom(Double.class)) {
      final double doubleValue = value.doubleValue();
      if (BigDecimal.valueOf(doubleValue).compareTo(value) == 0) {
        return returnType.cast(doubleValue);
      } else {
        throw new IllegalArgumentException();
      }
    } else if (returnType.isAssignableFrom(Float.class)) {
      final Float floatValue = value.floatValue();
      if (BigDecimal.valueOf(floatValue).compareTo(value) == 0) {
        return returnType.cast(floatValue);
      } else {
        throw new IllegalArgumentException();
      }
    } else {
      try {
        if (returnType.isAssignableFrom(BigInteger.class)) {
          return returnType.cast(value.toBigIntegerExact());
        } else if (returnType.isAssignableFrom(Long.class)) {
          return returnType.cast(value.longValueExact());
        } else if (returnType.isAssignableFrom(Integer.class)) {
          return returnType.cast(value.intValueExact());
        } else if (returnType.isAssignableFrom(Short.class)) {
          return returnType.cast(value.shortValueExact());
        } else if (returnType.isAssignableFrom(Byte.class)) {
          return returnType.cast(value.byteValueExact());
        } else {
          throw new ClassCastException("unsupported return type " + returnType.getSimpleName());
        }
      } catch (final ArithmeticException e) {
        throw new IllegalArgumentException(e);
      }
    }
  }