How to unpack COMP-3 digits using Java?

ascii, ebcdic, mainframe, packed-decimal

Solution

COMP-3 (or "packed decimal") data looks like this: 0x12345s, where "s" is C for positive, D for negative, or F for unsigned. Thus 0x12345c -> "12345", x012345d -> "-12345", and 0x12345f -> "12345".

You've got one obvious error: You're ignoring the nybble in the byte that contains the sign nybble (e.g., "5" above) if the sign is negative. In addition, you're working too hard at manipulating the nybbles, it's a simple bitwise-and or a 4-bit shift to isolate a nybble.

Try something like this (untested):

public String unpackData(String packedData, int decimalPointLocation) {
    String unpackedData = "";
    char[] characters = packedData.toCharArray();
    final int negativeSign = 13;
    for (int currentCharIndex = 0; currentCharIndex < characters.length; currentCharIndex++) {
        byte firstDigit = ((byte) characters[currentCharIndex]) >>> 4);
        byte secondDigit = ((byte) characters[currentCharIndex]) & 0x0F;
        unpackedData += String.valueOf(firstDigit);
        if (currentCharIndex == (characters.length - 1)) {
            if (secondDigit == negativeSign) {
                unpackedData = "-" + unpackedData;
            }
        } else {
            unpackedData += String.valueOf(secondDigit);
        }
    }
    if (decimalPointLocation > 0) {
        unpackedData = unpackedData.substring(0, (decimalPointLocation - 1)) + 
                        "." + 
                        unpackedData.substring(decimalPointLocation);
    }
    return unpackedData;
}

Problem

I have huge mainframe file and there are some packed digits in that file. I would like to know how to unpack following digit using java? packed digit : `?` I read tutorials for unpacking digits and found the following rule to count the number of bytes required to unpack digits : `total_number_of_bytes = (no. of digits + 1) / 2` I wrote the following code to unpack digits : ``` public String unpackData(String packedData, int decimalPointLocation) { String unpackedData = ""; char[] characters = packedData.toCharArray(); final int impliedPositive = 15; final int positiveNumber = 12; final int negativeNumber = 13; for (int currentCharIndex = 0; currentCharIndex < characters.length; currentCharIndex++) { byte[] unpackedDigits = unpackByte((byte) characters[currentCharIndex]); if(currentCharIndex == (characters.length - 1)) { if(unpackedDigits[1] == impliedPositive || unpackedDigits[1] == positiveNumber) { unpackedData += String.valueOf(unpackedDigits[0]); } else if(unpackedDigits[1] == negativeNumber) { unpackedData = "-" + unpackedData; } } else { unpackedData += String.valueOf(unpackedDigits[0]) + String.valueOf(unpackedDigits[1]); } } if(decimalPointLocation > 0) { unpackedData = unpackedData.substring(0, (decimalPointLocation - 1)) + "." + unpackedData.substring(decimalPointLocation); } return unpackedData; } private byte[] unpackByte(byte packedData) { byte firstDigit = (byte) (packedData >>> 4); firstDigit = setBitsToZero(firstDigit, 4, 8); //System.out.println(" firstDigit = "+ firstDigit + ", and its bit string after unpacking = " + getBitString(firstDigit, 7)); byte secondDigit = setBitsToZero(packedData, 4, 8); //System.out.println("second digit = " + secondDigit + ", and its bit string of second digit after unpcking = " + getBitString(secondDigit, 7)); byte[] unpackedData = new byte[2]; unpackedData[0] = firstDigit; unpackedData[1] = secondDigit; return unpackedData; } private byte setBitsToZero(byte number, int startBitPosition, int endBitPosition) { for (int i = startBitPosition; i < endBitPosition; i++) { number = (byte) (number & ~(1 << i)); } return number; } ``` This program works correctly for integer type values but it's not working for floating point type values. Can anyone please tell if my program is correct?

Original source

Related problems