📄 decimal.java
字号:
magnitude[14] = (byte) (value[3] >>> 8); magnitude[15] = (byte) (value[3]); return new java.math.BigDecimal(new java.math.BigInteger(signum, magnitude), scale); } else { // throw an exception here if nibbles is greater than 31 throw new java.lang.IllegalArgumentException("Decimal may only be up to 31 digits!"); } } /** * Build a Java <code>double</code> from a fixed point decimal byte representation. * * @throws IllegalArgumentException if the specified representation is not recognized. */ public static final double getDouble(byte[] buffer, int offset, int precision, int scale) throws java.io.UnsupportedEncodingException { // The byte-length of a packed decimal with precision <code>p</code> is always <code>p/2 + 1</code> int length = precision / 2 + 1; // check for sign. int signum; if ((buffer[offset + length - 1] & 0x0F) == 0x0D) { signum = -1; } else { signum = 1; } if (precision <= 9) { // can be handled by int without overflow. int value = packedNybblesToInt(buffer, offset, 0, length * 2 - 1); return signum * value / Math.pow(10, scale); } else if (precision <= 18) { // can be handled by long without overflow. long value = packedNybblesToLong(buffer, offset, 0, length * 2 - 1); return signum * value / Math.pow(10, scale); } else if (precision <= 27) { // get the value of last 9 digits (5 bytes). int lo = packedNybblesToInt(buffer, offset, (length - 5) * 2, 9); // get the value of another 9 digits (5 bytes). int me = packedNybblesToInt(buffer, offset, (length - 10) * 2 + 1, 9); // get the value of the rest digits. int hi = packedNybblesToInt(buffer, offset, 0, (length - 10) * 2 + 1); return signum * (lo / Math.pow(10, scale) + me * Math.pow(10, 9 - scale) + hi * Math.pow(10, 18 - scale)); } else if (precision <= 31) { // get the value of last 9 digits (5 bytes). int lo = packedNybblesToInt(buffer, offset, (length - 5) * 2, 9); // get the value of another 9 digits (5 bytes). int meLo = packedNybblesToInt(buffer, offset, (length - 10) * 2 + 1, 9); // get the value of another 9 digits (5 bytes). int meHi = packedNybblesToInt(buffer, offset, (length - 14) * 2, 9); // get the value of the rest digits. int hi = packedNybblesToInt(buffer, offset, 0, (length - 14) * 2); return signum * (lo / Math.pow(10, scale) + meLo * Math.pow(10, 9 - scale) + meHi * Math.pow(10, 18 - scale) + hi * Math.pow(10, 27 - scale)); } else { // throw an exception here if nibbles is greater than 31 throw new java.lang.IllegalArgumentException("Decimal may only be up to 31 digits!"); } } /** * Build a Java <code>long</code> from a fixed point decimal byte representation. * * @throws IllegalArgumentException if the specified representation is not recognized. */ public static final long getLong(byte[] buffer, int offset, int precision, int scale) throws java.io.UnsupportedEncodingException { if (precision > 31) { // throw an exception here if nibbles is greater than 31 throw new java.lang.IllegalArgumentException("Decimal may only be up to 31 digits!"); } // The byte-length of a packed decimal with precision <code>p</code> is always <code>p/2 + 1</code> int length = precision / 2 + 1; // check for sign. int signum; if ((buffer[offset + length - 1] & 0x0F) == 0x0D) { signum = -1; } else { signum = 1; } // compute the integer part only. int leftOfDecimalPoint = length * 2 - 1 - scale; long integer = 0; if (leftOfDecimalPoint > 0) { int i = 0; for (; i < leftOfDecimalPoint / 2; i++) { integer = integer * 10 + signum * ((buffer[offset + i] & 0xF0) >>> 4); // high nybble. integer = integer * 10 + signum * (buffer[offset + i] & 0x0F); // low nybble. } if ((leftOfDecimalPoint % 2) == 1) { // process high nybble of the last byte if necessary. integer = integer * 10 + signum * ((buffer[offset + i] & 0xF0) >>> 4); } } return integer; } //--------------entry points for runtime representation----------------------- /** * Write a Java <code>java.math.BigDecimal</code> to packed decimal bytes. */ public static final int bigDecimalToPackedDecimalBytes(byte[] buffer, int offset, java.math.BigDecimal b, int declaredPrecision, int declaredScale) throws ConversionException { // packed decimal may only be up to 31 digits. if (declaredPrecision > 31) { throw new ConversionException("Packed decimal may only be up to 31 digits!"); } // get absolute unscaled value of the BigDecimal as a String. String unscaledStr = b.unscaledValue().abs().toString(); // get precision of the BigDecimal. int bigPrecision = unscaledStr.length(); if (bigPrecision > 31) { throw new ConversionException("The numeric literal \"" + b.toString() + "\" is not valid because its value is out of range.", "42820", -405); } int bigScale = b.scale(); int bigWholeIntegerLength = bigPrecision - bigScale; if ((bigWholeIntegerLength > 0) && (!unscaledStr.equals("0"))) { // if whole integer part exists, check if overflow. int declaredWholeIntegerLength = declaredPrecision - declaredScale; if (bigWholeIntegerLength > declaredWholeIntegerLength) { throw new ConversionException("Overflow occurred during numeric data type conversion of \"" + b.toString() + "\".", "22003", -413); } } // convert the unscaled value to a packed decimal bytes. // get unicode '0' value. int zeroBase = '0'; // start index in target packed decimal. int packedIndex = declaredPrecision - 1; // start index in source big decimal. int bigIndex; if (bigScale >= declaredScale) { // If target scale is less than source scale, // discard excessive fraction. // set start index in source big decimal to ignore excessive fraction. bigIndex = bigPrecision - 1 - (bigScale - declaredScale); if (bigIndex < 0) { // all digits are discarded, so only process the sign nybble. buffer[offset + (packedIndex + 1) / 2] = (byte) ((b.signum() >= 0) ? 12 : 13); // sign nybble } else { // process the last nybble together with the sign nybble. buffer[offset + (packedIndex + 1) / 2] = (byte) (((unscaledStr.charAt(bigIndex) - zeroBase) << 4) + // last nybble ((b.signum() >= 0) ? 12 : 13)); // sign nybble } packedIndex -= 2; bigIndex -= 2; } else { // If target scale is greater than source scale, // pad the fraction with zero. // set start index in source big decimal to pad fraction with zero. bigIndex = declaredScale - bigScale - 1; // process the sign nybble. buffer[offset + (packedIndex + 1) / 2] = (byte) ((b.signum() >= 0) ? 12 : 13); // sign nybble for (packedIndex -= 2, bigIndex -= 2; bigIndex >= 0; packedIndex -= 2, bigIndex -= 2) { buffer[offset + (packedIndex + 1) / 2] = (byte) 0; } if (bigIndex == -1) { buffer[offset + (packedIndex + 1) / 2] = (byte) ((unscaledStr.charAt(bigPrecision - 1) - zeroBase) << 4); // high nybble packedIndex -= 2; bigIndex = bigPrecision - 3; } else { bigIndex = bigPrecision - 2; } } // process the rest. for (; bigIndex >= 0; packedIndex -= 2, bigIndex -= 2) { buffer[offset + (packedIndex + 1) / 2] = (byte) (((unscaledStr.charAt(bigIndex) - zeroBase) << 4) + // high nybble (unscaledStr.charAt(bigIndex + 1) - zeroBase)); // low nybble } // process the first nybble when there is one left. if (bigIndex == -1) { buffer[offset + (packedIndex + 1) / 2] = (byte) (unscaledStr.charAt(0) - zeroBase); packedIndex -= 2; } // pad zero in front of the big decimal if necessary. for (; packedIndex >= -1; packedIndex -= 2) { buffer[offset + (packedIndex + 1) / 2] = (byte) 0; } return declaredPrecision / 2 + 1; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -