Java BigDecimal to decimalToBytes(BigDecimal v, byte[] result, final int offset, int length)

Here you can find the source of decimalToBytes(BigDecimal v, byte[] result, final int offset, int length)

Description

decimal To Bytes

License

Apache License

Declaration

private static int decimalToBytes(BigDecimal v, byte[] result, final int offset, int length) 

Method Source Code


//package com.java2s;
//License from project: Apache License 

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

public class Main {
    private static final Integer MAX_BIG_DECIMAL_BYTES = 21;
    private static final byte ZERO_BYTE = (byte) 0x80;
    private static final byte NEG_TERMINAL_BYTE = (byte) 102;
    private static final int EXP_BYTE_OFFSET = 65;
    private static final int POS_DIGIT_OFFSET = 1;
    private static final int NEG_DIGIT_OFFSET = 101;
    private static final BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE);
    private static final BigInteger MIN_LONG = BigInteger.valueOf(Long.MIN_VALUE);
    private static final BigInteger ONE_HUNDRED = BigInteger.valueOf(100);

    private static int decimalToBytes(BigDecimal v, byte[] result, final int offset, int length) {
        int signum = v.signum();
        if (signum == 0) {
            result[offset] = ZERO_BYTE;//from  ww w  .  j a va 2 s.  c o m
            return 1;
        }
        int index = offset + length;
        int scale = v.scale();
        int expOffset = scale % 2 * (scale < 0 ? -1 : 1);
        int multiplyBy;
        BigInteger divideBy;
        if (expOffset == 0) {
            multiplyBy = 1;
            divideBy = ONE_HUNDRED;
        } else {
            multiplyBy = 10;
            divideBy = BigInteger.TEN;
        }
        // Normalize the scale based on what is necessary to end up with a base 100
        // decimal (i.e. 10.123e3)
        int digitOffset;
        BigInteger compareAgainst;
        if (signum == 1) {
            digitOffset = POS_DIGIT_OFFSET;
            compareAgainst = MAX_LONG;
            scale -= (length - 2) * 2;
            result[offset] = (byte) ((-(scale + expOffset) / 2 + EXP_BYTE_OFFSET) | 0x80);
        } else {
            digitOffset = NEG_DIGIT_OFFSET;
            compareAgainst = MIN_LONG;
            // Scale adjustment shouldn't include terminal byte in length
            scale -= (length - 2 - 1) * 2;
            result[offset] = (byte) (~(-(scale + expOffset) / 2 + EXP_BYTE_OFFSET + 128) & 0x7F);
            if (length <= MAX_BIG_DECIMAL_BYTES) {
                result[--index] = NEG_TERMINAL_BYTE;
            } else {
                // Adjust length and offset down because we don't have enough room
                length = MAX_BIG_DECIMAL_BYTES;
                index = offset + length;
            }
        }
        BigInteger bi = v.unscaledValue();
        // Use BigDecimal arithmetic until we can fit into a long
        while (bi.compareTo(compareAgainst) * signum > 0) {
            BigInteger[] dandr = bi.divideAndRemainder(divideBy);
            bi = dandr[0];
            int digit = dandr[1].intValue();
            result[--index] = (byte) (digit * multiplyBy + digitOffset);
            multiplyBy = 1;
            divideBy = ONE_HUNDRED;
        }
        long l = bi.longValue();
        do {
            long divBy = 100 / multiplyBy;
            long digit = l % divBy;
            l /= divBy;
            result[--index] = (byte) (digit * multiplyBy + digitOffset);
            multiplyBy = 1;
        } while (l != 0);

        return length;
    }
}

Related

  1. convertToBigDecimal(String s)
  2. convertToBigDecimal(String val)
  3. convertToBigDecimal(String value)
  4. convertToBigDecimal(String value)
  5. convertToFen(BigDecimal num1)
  6. decimalToString(BigDecimal value)
  7. toBeforeDecimalPointString(BigDecimal bigDecimal)
  8. toDouble(BigDecimal b, boolean allownull)
  9. toDouble(BigDecimal bigDecimal)