Java BigDecimal Log log2AbsCeil(BigDecimal x)

Here you can find the source of log2AbsCeil(BigDecimal x)

Description

log Abs Ceil

License

Open Source License

Declaration

public static int log2AbsCeil(BigDecimal x) 

Method Source Code


//package com.java2s;
//License from project: Open Source License 

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;

public class Main {
    public static int log2AbsCeil(BigInteger x) {
        if (x.signum() < 0) {
            return x.bitLength();
        }//  w  w  w  .ja  va  2s  .  co m
        if (x.signum() > 0) {
            return x.subtract(BigInteger.ONE).bitLength();
        }
        throw new IllegalArgumentException("x == 0");
    }

    public static int log2AbsCeil(BigDecimal x) {
        if (x.signum() == 0) {
            throw new IllegalArgumentException("x == 0");
        }
        if (x.signum() < 0) {
            x = x.negate();
        }
        final int compareTo1 = x.compareTo(BigDecimal.ONE);
        if (compareTo1 == 0) {
            return 0;
        } else if (compareTo1 > 0) {
            BigInteger xCeil = ceil(x);
            return log2AbsCeil(xCeil);
        } else {
            assert x.scale() > 0;
            final BigDecimal log2_10 = new BigDecimal("3.3219280949");
            final BigInteger scale2Ceil = ceil(BigDecimal.valueOf(x.scale()).multiply(log2_10));
            final int n = (int) scale2Ceil.doubleValue();
            if (n == Integer.MAX_VALUE) {
                throw new ArithmeticException("scale too long");
            }
            final BigInteger x2nCeil = ceil(x.multiply(new BigDecimal(twoPower(n))));
            return subInts(log2AbsCeil(x2nCeil), n);
        }
    }

    public static BigInteger ceil(BigDecimal x) {
        return x.setScale(0, RoundingMode.CEILING).unscaledValue();
    }

    static BigInteger multiply(BigInteger x, BigInteger y) {
        final int bitLengthX = x.bitLength();
        final int bitLengthY = y.bitLength();
        if (bitLengthX <= 256 || bitLengthY <= 256 || addInts(bitLengthX, bitLengthY) <= 3600) {
            return x.multiply(y);
        }
        return x.multiply(y);
    }

    public static BigInteger twoPower(int s) {
        if (s < 0) {
            throw new IllegalArgumentException("s < 0");
        }
        return BigInteger.ONE.shiftLeft(s);
    }

    public static int subInts(int a, int b) {
        if ((b > 0 && a < Integer.MIN_VALUE + b) || (b < 0 && a > Integer.MAX_VALUE + b)) {
            throw new ArithmeticException("int \"-\" overflow");
        }
        return a - b;
    }

    public static int addInts(int a, int b) {
        if ((a > 0 && b > Integer.MAX_VALUE - a) || (a < 0 && b < Integer.MIN_VALUE - a)) {
            throw new ArithmeticException("int \"+\" overflow");
        }
        return a + b;
    }
}

Related

  1. log(int base_int, BigDecimal x)
  2. log10(BigDecimal b)
  3. log10AbsCeil(BigDecimal x)