javaebcdicjt400

IBM Java Toolkit (jt400) EBCDIC signed number


AS400ZonedDecimal converter = new AS400ZonedDecimal(3, 0);
byte[] convertedBytesArray = converter.toBytes(new BigDecimal("-120"));

I can get characters '12}' from byte array, and that's right.

but when I try to use BigDecimal("120") to convert, then I got characters '120' but I want to get '12{'.

How to use AS400ZonedDecimal to convert BigDecimal positive to EBCDIC with sign ?

I try to search AS400ZonedDecimal API but no luck.


Solution

  • Main.java

    package org.example;
    
    import com.ibm.as400.access.AS400ZonedDecimal;
    
    import java.math.BigDecimal;
    import java.nio.charset.Charset;
    
    public class Main {
        // EBCDIC charset (IBM037)
        static Charset ebcdicCharset = Charset.forName("IBM037");
        public static void showEBCDICHexVal(byte[] bytes){
            for (byte b : bytes) {
                // Convert byte to hexadecimal string
                String hexValue = String.format("%02X", b);
                // Convert byte to EBCDIC character
                String ebcdicChar = new String(new byte[]{b}, ebcdicCharset);
                System.out.printf("Hex: %s, EBCDIC: %s%n", hexValue, ebcdicChar);
            }
        }
    
    
        public static void main(String[] args) {
            //BigDecimal nNum = new BigDecimal("-120");
    
            BigDecimal nNum = new BigDecimal("120");
    
            AS400ZonedDecimal converter = new AS400ZonedDecimal(3, 0);
            byte[] nNumBytesArray = converter.toBytes(nNum);
    
            // Display byte array in hexadecimal and EBCDIC decoded characters
            System.out.println("Hexadecimal and EBCDIC Representation:");
            showEBCDICHexVal(nNumBytesArray);
        } //main
    } //class
    

    Get 120 , output

    120
    Hex: F1, EBCDIC: 1
    Hex: F2, EBCDIC: 2
    Hex: F0, EBCDIC: 0
    

    Not expected 12{

    Main2.java

    package org.example;
    
    import java.math.BigDecimal;
    import com.ibm.as400.access.AS400ZonedDecimal;
    import java.nio.charset.Charset;
    
    public class Main2 {
        // EBCDIC charset (IBM037)
        static Charset ebcdicCharset = Charset.forName("IBM037");
        public static void showEBCDICHexVal(byte[] bytes){
            for (byte b : bytes) {
                // Convert byte to hexadecimal string
                String hexValue = String.format("%02X", b);
                // Convert byte to EBCDIC character
                String ebcdicChar = new String(new byte[]{b}, ebcdicCharset);
                System.out.printf("Hex: %s, EBCDIC: %s%n", hexValue, ebcdicChar);
            }
        }
        public static void main(String[] args) throws Exception {
            // EBCDIC string "12}" representing the zoned decimal encoded -120
            //String ebcdicString = "12}";
            String ebcdicString = "12{";
    
            // EBCDIC charset (IBM037)
            Charset ebcdicCharset = Charset.forName("IBM037");
    
            // Convert the string to EBCDIC byte array
            byte[] ebcdicBytes = ebcdicString.getBytes(ebcdicCharset);
    
            showEBCDICHexVal(ebcdicBytes);
    
            // Interpret the byte array as a zoned decimal to convert it back to BigDecimal
            // AS400ZonedDecimal takes length and scale, here length is 3 (for 3 digits) and scale is 0 (no decimal places)
            AS400ZonedDecimal converter = new AS400ZonedDecimal(3, 0);
    
            // Convert byte array to BigDecimal
            BigDecimal result = (BigDecimal) converter.toObject(ebcdicBytes);
    
            // Print the result
            System.out.println("Converted BigDecimal: " + result);
        }
    }
    

    Input 12{ get 120

    Hex: F1, EBCDIC: 1
    Hex: F2, EBCDIC: 2
    Hex: C0, EBCDIC: {
    Converted BigDecimal: 120
    

    compare

    Hex: F1, EBCDIC: 1 | Hex: F1, EBCDIC: 1
    Hex: F2, EBCDIC: 2 | Hex: F2, EBCDIC: 2
    Hex: F0, EBCDIC: 0 | Hex: C0, EBCDIC: {
    

    if input positive number, you must change FX to CX. (X is 0,1,3,4,5,6,7,8,9)

    hard code rule:

    modify the last element of the byte array.

    You can do it yourself.

    Hex value F0 to C0, F1 to C1,.....

    You can use put your string (12{) into Main2.java get output BigDecimal (120) to verify your encode string.

    ** Hard code test**

    Main2.java

    //byte[] ebcdicBytes = ebcdicString.getBytes(ebcdicCharset);
    
    byte[] ebcdicBytes = {(byte)0xF1, (byte)0xF2, (byte)0xC1};
    

    12A -> 121

    Hex: F1, EBCDIC: 1
    Hex: F2, EBCDIC: 2
    Hex: C1, EBCDIC: A
    Converted BigDecimal: 121
    
        // Custom method to convert BigDecimal to EBCDIC Zoned Decimal format
        public static byte[] convertToZonedDecimal(BigDecimal number) {
            // Convert the BigDecimal to string representation
            String numStr = number.abs().toPlainString();
            int length = numStr.length();
    
            // Create a byte array for the EBCDIC zoned decimal
            byte[] ebcdicBytes = new byte[length];
    
            // Fill the byte array with EBCDIC values for the digits
            for (int i = 0; i < length - 1; i++) {
                ebcdicBytes[i] = (byte) (0xF0 + (numStr.charAt(i) - '0'));
            }
    
            // Handle the last byte with the appropriate sign
            char lastChar = numStr.charAt(length - 1);
            if (number.signum() >= 0) {
                // Positive: Convert last digit with positive sign encoding
                ebcdicBytes[length - 1] = (byte) (0xC0 + (lastChar - '0'));  // Positive sign -> C0, C1, ..., C9
            } else {
                // Negative: Convert last digit with negative sign encoding
                ebcdicBytes[length - 1] = (byte) (0xD0 + (lastChar - '0'));  // Negative sign -> D0, D1, ..., D9
            }
    
            return ebcdicBytes;
        }
    

    Your Code:

    byte[] convertedBytesArray = converter.toBytes(new BigDecimal("-120"));
    

    Use convertToZonedDecimal code:

    byte[] convertedBytesArray = convertToZonedDecimal(new BigDecimal("-120"));
    

    Final Answer:

    Main.java

    package org.example;
    
    import com.ibm.as400.access.AS400ZonedDecimal;
    
    import java.math.BigDecimal;
    import java.nio.charset.Charset;
    
    public class Main {
        // EBCDIC charset (IBM037)
        static Charset ebcdicCharset = Charset.forName("IBM037");
    
        // Custom method to convert BigDecimal to EBCDIC Zoned Decimal format
        public static byte[] convertToZonedDecimal(BigDecimal number) {
            // Convert the BigDecimal to string representation
            String numStr = number.abs().toPlainString();
            int length = numStr.length();
    
            // Create a byte array for the EBCDIC zoned decimal
            byte[] ebcdicBytes = new byte[length];
    
            // Fill the byte array with EBCDIC values for the digits
            for (int i = 0; i < length - 1; i++) {
                ebcdicBytes[i] = (byte) (0xF0 + (numStr.charAt(i) - '0'));
            }
    
            // Handle the last byte with the appropriate sign
            char lastChar = numStr.charAt(length - 1);
            if (number.signum() >= 0) {
                // Positive: Convert last digit with positive sign encoding
                ebcdicBytes[length - 1] = (byte) (0xC0 + (lastChar - '0'));  // Positive sign -> C0, C1, ..., C9
            } else {
                // Negative: Convert last digit with negative sign encoding
                ebcdicBytes[length - 1] = (byte) (0xD0 + (lastChar - '0'));  // Negative sign -> D0, D1, ..., D9
            }
    
            return ebcdicBytes;
        }
        public static void showEBCDICHexVal(byte[] bytes){
            for (byte b : bytes) {
                // Convert byte to hexadecimal string
                String hexValue = String.format("%02X", b);
                // Convert byte to EBCDIC character
                String ebcdicChar = new String(new byte[]{b}, ebcdicCharset);
                System.out.printf("Hex: %s, EBCDIC: %s%n", hexValue, ebcdicChar);
            }
        }
    
    
        public static void main(String[] args) {
            BigDecimal nNum = new BigDecimal("121");
            //AS400ZonedDecimal converter = new AS400ZonedDecimal(3, 0);
            //byte[] nNumBytesArray = converter.toBytes(nNum);
            byte[] nNumBytesArray = convertToZonedDecimal(nNum);
            // Display byte array in hexadecimal and EBCDIC decoded characters
            System.out.println("Hexadecimal and EBCDIC Representation:");
            showEBCDICHexVal(nNumBytesArray);
        } //main
    } //class