Six Stars

[resolved] Packed Decimals

Hello,
I have a positional file with some fields being in Packed Decimal format. I have successfully ceated possitional file schema. How do I convert values that are in Packed decimal format to regular decimals? Also i saw something about tFileInputEBCDIC component but i can't find it in my studio. Could anyone give me any suggestions?
Thank you
1 ACCEPTED SOLUTION

Accepted Solutions
Six Stars

Re: [resolved] Packed Decimals

This is resolved now the solution was:
    Create a positional file in the repository where the columns of Packed decimals are of type byte[]
    Create routine ParsePackedDecimal with a method parse to convert byte[] packed decimal to long integer.
    Method  :
public static long parse(byte[] pdIn) throws Exception {
      // Convert packed decimal to long
        final int PlusSign = 0x0C;       // Plus sign
        final int MinusSign = 0x0D;      // Minus
        final int NoSign = 0x0F;         // Unsigned
        final int DropHO = 0xFF;         // AND mask to drop HO sign bits
        final int GetLO  = 0x0F;         // Get only LO digit
  long val = 0;                    // Value to return
   
        for(int i=0; i < pdIn.length; i++) {
           int aByte = pdIn & DropHO; // Get next 2 digits & drop sign bits
           if(i == pdIn.length - 1) {    // last digit?
              int digit = aByte >> 4;    // First get digit
              val = val*10 + digit;
//               System.out.println("digit=" + digit + ", val=" + val);
              int sign = aByte & GetLO;  // now get sign
              if (sign == MinusSign)
                 val = -val;
              else {
                 // Do we care if there is an invalid sign?
                 if(sign != PlusSign && sign != NoSign)
                    throw new Exception("OC7");
              }
           }else {
              int digit = aByte >> 4;    // HO first  
              val = val*10 + digit;
//               System.out.println("digit=" + digit + ", val=" + val);
              digit = aByte & GetLO;      // now LO
              val = val*10 + digit;
//               System.out.println("digit=" + digit + ", val=" + val);
           }
        }
  return val;
  } // end parse()

3. Connect tFileInputPositional (In Basic settings check the box "Use byte length as the cardinality" and in Advanced settings uncheck the box "Trim all columns") to TXMLMap and tXMLMap to tfileOutputDElimited or any other format you want to use.  In the mapping,  expressions tool needs to be used to transform packed decimal to its string representation:
Expression to convert packed decimal from byte[] to long:
ParsePackedDecimal.parse(YourRow.YourColumnName)
My example:
ParsePackedDecimal.parse(row9.DLY_DRAFT_AMT)
Then we need to convert this long integer value to our desired decimal precision in the next expression:
Numeric.convertString2BigDecimal("9(7)V99",String.valueOf(Var.Var1)).toString()
There is function  Numeric.convertImpliedDecimalFormat, but it should not be used as it is losing precision.
4. Var.Var2 is your parsed and formatted packed decimal as a string and ready to be written to xML or other file.
6 REPLIES
Moderator

Re: [resolved] Packed Decimals

Hi,
The EBCDIC components have been deprecated several version ago to be replaced by Talend Data Mapper.
The old components have been published on Talend Exchange and are provided as is, without support from Talend for version 6.0+.
https://exchange.talend.com/
Best regards
Sabrina
--
Don't forget to give kudos when a reply is helpful and click Accept the solution when you think you're good with it.
Six Stars

Re: [resolved] Packed Decimals

Hello, Thank you for the reply,
I now have the file schema, and only a few fields are in S9(7)V99 or similar formats, is there any simple way to tell talend to treat those fields as such? It gives me null if I just set it as BigDecimal.
Moderator

Re: [resolved] Packed Decimals

Hi,
Could you please elaborate your case with an example with input and expected output values?
Best regards
Sabrina
--
Don't forget to give kudos when a reply is helpful and click Accept the solution when you think you're good with it.
Six Stars

Re: [resolved] Packed Decimals

I have a positional file with rows like that - packed decimals are not showing :
C910124141094141090011604263N1AB7AP0GL655147 fþ16042616SENTRA 1.8 S CV160426DF BDSALSENTR    
C542134136294136290011604263N1AB7AP4GL653515 Ÿ^16042616SENTRA 1.8 S CV160426DF BDSALSENTR    
C910124141174141170011604263N1AB7AP5GL654981 fþ16042616SENTRA 1.8 S CV160426DF BDSALSENTR    
C521124136334136330011604263N1AB7AP7GL656523 16042616SENTRA 1.8SV  C160426DF ¬øBDSALSENTR     with the output format similar to:
C--52112---413633---413633---001---160426---3N1AB7AP7GL656523---(some S9(7)V99 format number) ---160426---16---SENTRA 1.8SV  C--160426--DF--(some S9(7)V99 format number)--BDSALSENTR
I made metadata for the positional file, but how to parse those S9(7)V99 numbers?
Is there any function I could use?
Six Stars

Re: [resolved] Packed Decimals

This is resolved now the solution was:
    Create a positional file in the repository where the columns of Packed decimals are of type byte[]
    Create routine ParsePackedDecimal with a method parse to convert byte[] packed decimal to long integer.
    Method  :
public static long parse(byte[] pdIn) throws Exception {
      // Convert packed decimal to long
        final int PlusSign = 0x0C;       // Plus sign
        final int MinusSign = 0x0D;      // Minus
        final int NoSign = 0x0F;         // Unsigned
        final int DropHO = 0xFF;         // AND mask to drop HO sign bits
        final int GetLO  = 0x0F;         // Get only LO digit
  long val = 0;                    // Value to return
   
        for(int i=0; i < pdIn.length; i++) {
           int aByte = pdIn & DropHO; // Get next 2 digits & drop sign bits
           if(i == pdIn.length - 1) {    // last digit?
              int digit = aByte >> 4;    // First get digit
              val = val*10 + digit;
//               System.out.println("digit=" + digit + ", val=" + val);
              int sign = aByte & GetLO;  // now get sign
              if (sign == MinusSign)
                 val = -val;
              else {
                 // Do we care if there is an invalid sign?
                 if(sign != PlusSign && sign != NoSign)
                    throw new Exception("OC7");
              }
           }else {
              int digit = aByte >> 4;    // HO first  
              val = val*10 + digit;
//               System.out.println("digit=" + digit + ", val=" + val);
              digit = aByte & GetLO;      // now LO
              val = val*10 + digit;
//               System.out.println("digit=" + digit + ", val=" + val);
           }
        }
  return val;
  } // end parse()

3. Connect tFileInputPositional (In Basic settings check the box "Use byte length as the cardinality" and in Advanced settings uncheck the box "Trim all columns") to TXMLMap and tXMLMap to tfileOutputDElimited or any other format you want to use.  In the mapping,  expressions tool needs to be used to transform packed decimal to its string representation:
Expression to convert packed decimal from byte[] to long:
ParsePackedDecimal.parse(YourRow.YourColumnName)
My example:
ParsePackedDecimal.parse(row9.DLY_DRAFT_AMT)
Then we need to convert this long integer value to our desired decimal precision in the next expression:
Numeric.convertString2BigDecimal("9(7)V99",String.valueOf(Var.Var1)).toString()
There is function  Numeric.convertImpliedDecimalFormat, but it should not be used as it is losing precision.
4. Var.Var2 is your parsed and formatted packed decimal as a string and ready to be written to xML or other file.
Moderator

Re: [resolved] Packed Decimals

Hi,
Great it is fixed. Thanks for your solution.
Best regards
Sabrina
--
Don't forget to give kudos when a reply is helpful and click Accept the solution when you think you're good with it.