Here you can find the source of toDecimal(BigInteger value, byte[] buffer, int offset, int length, int itemLength, byte pos)
Parameter | Description |
---|---|
value | the value. |
buffer | where to write the value. |
offset | index of the first byte in the buffer. |
length | the number of digits to write, must be at least 18. |
itemLength | length of the value in bytes. |
pos | the positive sign to use: 0xC for DECIMAL, 0xF for PACF. |
public static void toDecimal(BigInteger value, byte[] buffer, int offset, int length, int itemLength, byte pos)
//package com.java2s; /******************************************************************************* * Copyright ? 2006, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors:/*w w w . j a v a 2s .co m*/ * IBM Corporation - initial API and implementation * *******************************************************************************/ import java.math.BigInteger; public class Main { /** * This is BigInteger.valueOf( 100000000000000000L ). */ private final static BigInteger TEN_TO_THE_SEVENTEENTH = BigInteger.valueOf(100000000000000000L); /** * Converts a value to DECIMAL or PACF format, writing it into the buffer at * the specified position. * * @param value the value. * @param buffer where to write the value. * @param offset index of the first byte in the buffer. * @param length the number of digits to write. * @param itemLength length of the value in bytes. * @param pos the positive sign to use: 0xC for DECIMAL, 0xF for PACF. */ public static void toDecimal(int value, byte[] buffer, int offset, int length, int itemLength, byte pos) { int bufferIndex = offset + itemLength - 1; // Make sure the value is positive and set the sign. if (value >= 0) { buffer[bufferIndex] = pos; } else { value = -value; buffer[bufferIndex] = (byte) 0x0D; } // Write the digits, starting from the end and working backwards. boolean wroteLow = true; int digitsToWrite = length; while (value > 0 && digitsToWrite > 0) { // Set the high nibble of the current byte. buffer[bufferIndex] |= (byte) ((value % 10) << 4); digitsToWrite--; wroteLow = false; value = value / 10; // We're done with this byte. bufferIndex--; if (value == 0 || digitsToWrite == 0) { // We're done with value. break; } // Set the low nibble of the current byte. buffer[bufferIndex] = (byte) (value % 10); digitsToWrite--; wroteLow = true; value = value / 10; } // Fill with zeros if neccessary. if (digitsToWrite > 0) { if (wroteLow) { // Since we just wrote the low nibble of a byte, the high nibble // is already a zero. We can move to the next byte. digitsToWrite--; bufferIndex--; } while (digitsToWrite > 0) { // Zero out two nibbles at a time. buffer[bufferIndex] = 0; bufferIndex--; digitsToWrite -= 2; } } } /** * Converts a value to DECIMAL or PACF format, writing it into the buffer at * the specified position. * * @param value the value. * @param buffer where to write the value. * @param offset index of the first byte in the buffer. * @param length the number of digits to write. * @param itemLength length of the value in bytes. * @param pos the positive sign to use: 0xC for DECIMAL, 0xF for PACF. */ public static void toDecimal(long value, byte[] buffer, int offset, int length, int itemLength, byte pos) { int bufferIndex = offset + itemLength - 1; // Make sure the value is positive and set the sign. if (value >= 0) { buffer[bufferIndex] = pos; } else { value = -value; buffer[bufferIndex] = (byte) 0x0D; } // Write the digits, starting from the end and working backwards. boolean wroteLow = true; int digitsToWrite = length; while (value > 0 && digitsToWrite > 0) { // Set the high nibble of the current byte. buffer[bufferIndex] |= (byte) ((value % 10) << 4); digitsToWrite--; wroteLow = false; value = value / 10; // We're done with this byte. bufferIndex--; if (value == 0 || digitsToWrite == 0) { // We're done with value. break; } // Set the low nibble of the current byte. buffer[bufferIndex] = (byte) (value % 10); digitsToWrite--; wroteLow = true; value = value / 10; } // Fill with zeros if neccessary. if (digitsToWrite > 0) { if (wroteLow) { // Since we just wrote the low nibble of a byte, the high nibble // is already a zero. We can move to the next byte. digitsToWrite--; bufferIndex--; } while (digitsToWrite > 0) { // Zero out two nibbles at a time. buffer[bufferIndex] = 0; bufferIndex--; digitsToWrite -= 2; } } } /** * Converts a value to DECIMAL or PACF format, writing it into the buffer at * the specified position. Do not use this method if the data has fewer than * 18 digits. In that case, do this instead: * toDecimal( value.longValue(), ... ) ). * * @param value the value. * @param buffer where to write the value. * @param offset index of the first byte in the buffer. * @param length the number of digits to write, must be at least 18. * @param itemLength length of the value in bytes. * @param pos the positive sign to use: 0xC for DECIMAL, 0xF for PACF. */ public static void toDecimal(BigInteger value, byte[] buffer, int offset, int length, int itemLength, byte pos) { if (value.bitLength() < 63) { // The value can be stored in a long, so use the method that doesn't // operate on BigIntegers. It's much faster than this one. toDecimal(value.longValue(), buffer, offset, length, itemLength, pos); return; } // Split the value into two BigIntegers that can be converted to longs. BigInteger[] topAndBottom = value.divideAndRemainder(TEN_TO_THE_SEVENTEENTH); // Write the bottom half and sign using the other toDecimal method. int byteOfSeventeethDigit = offset + (length / 2) - 8; long bottom = topAndBottom[1].longValue(); toDecimal(bottom, buffer, byteOfSeventeethDigit, 17, 9, pos); // Convert the top half to a long, and make sure it's positive since the // sign has already been written. long top = topAndBottom[0].longValue(); if (top < 0) { top = -top; } // Write the top half of the digits. Start from the end (digit 18) and // work backwards. int digitsToWrite = length - 17; int bufferIndex = byteOfSeventeethDigit - 1; while (top > 0 && digitsToWrite > 0) { // Set the low nibble of the current byte. buffer[bufferIndex] = (byte) (top % 10); digitsToWrite--; top = top / 10; if (top == 0 || digitsToWrite == 0) { // We're done with top. If any zeros need to be added, we can // skip the high nibble of this byte. It's already a zero. bufferIndex--; digitsToWrite--; break; } // Set the high nibble of the current byte. buffer[bufferIndex] |= (byte) ((top % 10) << 4); digitsToWrite--; top = top / 10; // We're done with this byte. bufferIndex--; } // Fill with zeros as necessary. while (digitsToWrite > 0) { // Zero out two nibbles at a time. buffer[bufferIndex] = 0; bufferIndex--; digitsToWrite -= 2; } } }