public static BigDecimal toDecimal(int precision, int scale, byte[] value) {
		//
        final boolean positive = (value[0] & 0x80) == 0x80;
        value[0] ^= 0x80;
        if (!positive) {
        	 for (int i = 0; i < value.length; i++) {
        		 value[i] ^= 0xFF;
             }
        }

        //
        final int x = precision - scale;
        final int ipDigits = x / DIGITS_PER_4BYTES;
        final int ipDigitsX = x - ipDigits * DIGITS_PER_4BYTES;
        final int ipSize = (ipDigits << 2) + DECIMAL_BINARY_SIZE[ipDigitsX];
        int offset = DECIMAL_BINARY_SIZE[ipDigitsX];
        BigDecimal ip = offset > 0 ? BigDecimal.valueOf(CodecUtils.toInt(value, 0, offset)) : BigDecimal.ZERO;
        for(; offset < ipSize; offset += 4) {
        	final int i = CodecUtils.toInt(value, offset, 4);
        	ip = ip.movePointRight(DIGITS_PER_4BYTES).add(BigDecimal.valueOf(i));
        }

        // 
        int shift = 0;
        BigDecimal fp = BigDecimal.ZERO;
        for (; shift + DIGITS_PER_4BYTES <= scale; shift += DIGITS_PER_4BYTES, offset += 4) {
            final int i = CodecUtils.toInt(value, offset, 4);
            fp = fp.add(BigDecimal.valueOf(i).movePointLeft(shift + DIGITS_PER_4BYTES));
        }
        if(shift < scale) {
        	final int i = CodecUtils.toInt(value, offset, DECIMAL_BINARY_SIZE[scale - shift]);
            fp = fp.add(BigDecimal.valueOf(i).movePointLeft(scale));
        }
        
        //
        return positive ? POSITIVE_ONE.multiply(ip.add(fp)) : NEGATIVE_ONE.multiply(ip.add(fp));
	}