// Packed Decimal (IBM format) is stored with each digit or special in a nibble. // All decimal digits represent themselves as nibbles. // // I'm presuming in this that P characters are not used in the picture; they // complicate the situation. The value should be descaled first if so. static public final byte PD_PLUS=12; static public final byte PD_MINUS=13; static public final byte PD_PAD=14; static public final byte PD_UNSIGNED=15; // The picture length is the number of 9's, not including the assumed decimal V character // or the sign character S. boolean usePadding=((picLength&1)==0); // true if even number of digits // You need to know the sign position; if always using the same sign position, // you can eliminate the alternate cases. // byte[] memory is the memory in which to store // int offset is the offset into the memory in which to store // The itemSize is the number of bytes of the packed-decimal number. boolean negative= false; // absbuffer is the string representation of the number String absbuffer= storeValue.toString(); // aka, "123.456" int length= absbuffer.length(); // Normalize the absbuffer if (length > 2 && absbuffer.startsWith("0.")) { absbuffer= absbuffer.substring(1); // .xxx length--; } else if (length > 1 && absbuffer.charAt(0) == '-') { negative= true; if (length > 3 && absbuffer.startsWith("-0.")) { absbuffer= absbuffer.substring(2); length -= 2; } else { absbuffer= absbuffer.substring(1); length--; } } // Now, absbuffer contains the version we care about, an absolute numeric string int byteLow= PD_PAD; // never actually uses PD_PAD, impossible case int byteHigh= PD_PAD; // never actually uses PD_PAD, impossible case int decimal= absbuffer.indexOf((int) '.'); if (decimal < 0) decimal= length; int load= decimal - (picLength - temporaryPlace); int signNibble; if ((signPosition == SIGN_LEADING || signPosition == SIGN_LEADING_SEPARATE)) { // sign leading signNibble= negative ? PD_MINUS : PD_PLUS; // leading body if (usePadding) { byteLow= signNibble; byteHigh= 0; // begin storebyte memory[offset++]= (byte) ((byteLow << 4) | byteHigh); // end storebyte } else { byteLow= signNibble; // begin getdigit if (load >= 0) { if (load == decimal) load++; // skip decimal point if (load >= length) byteHigh= 0; else { switch (absbuffer.charAt(load)) { case '0' : byteHigh= 0; break; case '1' : byteHigh= 1; break; case '2' : byteHigh= 2; break; case '3' : byteHigh= 3; break; case '4' : byteHigh= 4; break; case '5' : byteHigh= 5; break; case '6' : byteHigh= 6; break; case '7' : byteHigh= 7; break; case '8' : byteHigh= 8; break; case '9' : byteHigh= 9; break; case '+' : byteHigh= PD_PLUS; break; case '-' : byteHigh= PD_MINUS; break; default : byteHigh= PD_PAD; break; } } } else byteHigh= 0; load++; // end getdigit // begin storebyte memory[offset++]= (byte) ((byteLow << 4) | byteHigh); // end storebyte } // main body for (int i= 1; i < itemSize; i++) { // begin getdigit if (load >= 0) { if (load == decimal) load++; // skip decimal point if (load >= length) byteLow= 0; else { switch (absbuffer.charAt(load)) { case '0' : byteLow= 0; break; case '1' : byteLow= 1; break; case '2' : byteLow= 2; break; case '3' : byteLow= 3; break; case '4' : byteLow= 4; break; case '5' : byteLow= 5; break; case '6' : byteLow= 6; break; case '7' : byteLow= 7; break; case '8' : byteLow= 8; break; case '9' : byteLow= 9; break; case '+' : byteLow= PD_PLUS; break; case '-' : byteLow= PD_MINUS; break; default : byteLow= PD_PAD; break; } } } else byteLow= 0; load++; // end getdigit // begin getdigit if (load >= 0) { if (load == decimal) load++; // skip decimal point if (load >= length) byteHigh= 0; else { switch (absbuffer.charAt(load)) { case '0' : byteHigh= 0; break; case '1' : byteHigh= 1; break; case '2' : byteHigh= 2; break; case '3' : byteHigh= 3; break; case '4' : byteHigh= 4; break; case '5' : byteHigh= 5; break; case '6' : byteHigh= 6; break; case '7' : byteHigh= 7; break; case '8' : byteHigh= 8; break; case '9' : byteHigh= 9; break; case '+' : byteHigh= PD_PLUS; break; case '-' : byteHigh= PD_MINUS; break; default : byteHigh= PD_PAD; break; } } } else byteHigh= 0; load++; // end getdigit // begin storebyte memory[offset++]= (byte) ((byteLow << 4) | byteHigh); // end storebyte } // trailing body is empty } else { // sign trailing or unsigned if (signPosition == SIGN_NONE) signNibble= PD_UNSIGNED; else signNibble= negative ? PD_MINUS : PD_PLUS; // leading body int i= 0; if (usePadding) { byteLow= 0; // begin getdigit if (load >= 0) { if (load == decimal) load++; // skip decimal point if (load >= length) byteHigh= 0; else { switch (absbuffer.charAt(load)) { case '0' : byteHigh= 0; break; case '1' : byteHigh= 1; break; case '2' : byteHigh= 2; break; case '3' : byteHigh= 3; break; case '4' : byteHigh= 4; break; case '5' : byteHigh= 5; break; case '6' : byteHigh= 6; break; case '7' : byteHigh= 7; break; case '8' : byteHigh= 8; break; case '9' : byteHigh= 9; break; case '+' : byteHigh= PD_PLUS; break; case '-' : byteHigh= PD_MINUS; break; default : byteHigh= PD_PAD; break; } } } else byteHigh= 0; load++; // end getdigit // begin storebyte memory[offset++]= (byte) ((byteLow << 4) | byteHigh); // end storebyte i= 1; } // main body is same as above int itemSizeMinus1= itemSize - 1; for (; i < itemSizeMinus1; i++) { // begin getdigit if (load >= 0) { if (load == decimal) load++; // skip decimal point if (load >= length) byteLow= 0; else { switch (absbuffer.charAt(load)) { case '0' : byteLow= 0; break; case '1' : byteLow= 1; break; case '2' : byteLow= 2; break; case '3' : byteLow= 3; break; case '4' : byteLow= 4; break; case '5' : byteLow= 5; break; case '6' : byteLow= 6; break; case '7' : byteLow= 7; break; case '8' : byteLow= 8; break; case '9' : byteLow= 9; break; case '+' : byteLow= PD_PLUS; break; case '-' : byteLow= PD_MINUS; break; default : byteLow= PD_PAD; break; } } } else byteLow= 0; load++; // end getdigit // begin getdigit if (load >= 0) { if (load == decimal) load++; // skip decimal point if (load >= length) byteHigh= 0; else { switch (absbuffer.charAt(load)) { case '0' : byteHigh= 0; break; case '1' : byteHigh= 1; break; case '2' : byteHigh= 2; break; case '3' : byteHigh= 3; break; case '4' : byteHigh= 4; break; case '5' : byteHigh= 5; break; case '6' : byteHigh= 6; break; case '7' : byteHigh= 7; break; case '8' : byteHigh= 8; break; case '9' : byteHigh= 9; break; case '+' : byteHigh= PD_PLUS; break; case '-' : byteHigh= PD_MINUS; break; default : byteHigh= PD_PAD; break; } } } else byteHigh= 0; load++; // end getdigit // begin storebyte memory[offset++]= (byte) ((byteLow << 4) | byteHigh); // end storebyte } // trailing body // begin getdigit if (load >= 0) { if (load == decimal) load++; // skip decimal point if (load >= length) byteLow= 0; else { switch (absbuffer.charAt(load)) { case '0' : byteLow= 0; break; case '1' : byteLow= 1; break; case '2' : byteLow= 2; break; case '3' : byteLow= 3; break; case '4' : byteLow= 4; break; case '5' : byteLow= 5; break; case '6' : byteLow= 6; break; case '7' : byteLow= 7; break; case '8' : byteLow= 8; break; case '9' : byteLow= 9; break; case '+' : byteLow= PD_PLUS; break; case '-' : byteLow= PD_MINUS; break; default : byteLow= PD_PAD; break; } } } else byteLow= 0; load++; // end getdigit byteHigh= signNibble; // begin storebyte memory[offset++]= (byte) ((byteLow << 4) | byteHigh); // end storebyte }