Joined: 25 Nov 2007 Posts: 3 Location: chennai, india
Hi,
I need to convert a 8 byte binary number (SQL Data type BIGINT) to its equivalent Packed Decimal Number, and this decimal number is to be unpacked.
Similarly i should also need to do the reverse of above- pack the data, and convert it to 8 byte binary number. How can i do that? CVD, CVB work only on 4 byte numbers. My module is 31 bit module. Can anyone help me out here?
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
(I'm assuming Assembler)
Use "Load Grande" to load your doubleword binary value into a 64-Bit register and use a "Convert to Decimal Grande" to convert the 64-Bit doubleword into a 16-Byte Packed-Decimal/Quadword. Using 64-Bit R15 as an example, which should be OK -
Code:
QWORD DS L ALIGNED 16-BYTE QUADWORD
DWORD DS D ALIGNED 8-BYTE DOUBLEWORD
LG R15,DWORD LOAD INTO 64-BIT REGISTER
CVDG R15,QWORD MAKE IT 16-BYTE PACKED-DECIMAL
This can be done in COBOL, using the ARITH(EXTEND) compiler option.
Joined: 07 Feb 2009 Posts: 1306 Location: Vilnius, Lithuania
Bill O'Boyle wrote:
(I'm assuming Assembler)
Use "Load Grande" to load your doubleword binary value into a 64-Bit register and use a "Convert to Decimal Grande" to convert the 64-Bit doubleword into a 16-Byte Packed-Decimal/Quadword. Using 64-Bit R15 as an example, which should be OK -
Code:
QWORD DS L ALIGNED 16-BYTE QUADWORD
DWORD DS D ALIGNED 8-BYTE DOUBLEWORD
LG R15,DWORD LOAD INTO 64-BIT REGISTER
CVDG R15,QWORD MAKE IT 16-BYTE PACKED-DECIMAL
This can be done in COBOL, using the ARITH(EXTEND) compiler option.
I'm unsure about PL/I....
PL/I can also handle it, compiler option
Code:
*process limits(fixeddec(15,31) fixedbin(31,63));
which lets you use:
Code:
DCL BIGDEC FIXED (31); /* and */
DCL BIGBIN FIXED BIN (63);
It was introduced in Enterprise PL/I V3.5, and possibly even earlier, but I don't have older manuals available.
Joined: 25 Nov 2007 Posts: 3 Location: chennai, india
Yes i am writing in Assembler.
I am aware of grand instructions CVDG and CVBG which can be used to convert 8 byte data to binary and vice-versa. But once i convert binary to decimal using CVDG, i need to unpack the decimal value. As far as i know, using UNPK i can only get unpacked value of 16 bytes. In 8 byte data, the unpacked data can go beyond 8 bytes(i am thinking that for maximum allowed BIGINT value, unpacked data can be upto 19 digits.) I don think there is UNPK grand instr. do i need to use TR and a table with appropriate values to translate? Any other way?
The following (untested) should also accomplish your goal:
Code:
MASK DC X'21',30X'20'
UNPKAREA DS CL31
DWORD DS D
QWORD DS L
LG R15,DWORD R15 = BINARY VALUE
UNPKQWD CVDG R15,QWORD MAKE IT QUADWORD-DECIMAL
MVC UNPKAREA,MASK MOVE EDIT MASK TO UNPKAREA
ED UNPKAREA(31),QWORD UNPACK QUADWORD USING MASK
BNL NOTNEG TEST SIGN - IF NOT NEG, CONT
NI UNPKAREA+L'UNPKAREA-1,X'DF' MAKE NEGATIVE - SIGN = X'D'
NOTNEG EQU *
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
Ron,
Yes, ED is one of the SS instructions with a 1-Byte length (max=X'FF'/256), is a lot less code and I didn't think of it at O'Dark Thirty (was up doing maintenance, not by choice).
But, the reverse UNPACKED CL31 <---> DBLWORD-BINARY will be an exercise for the OP as a PACK has a 4-Bit max-length for Operand2 of X'F'/16.
The MVO was included as a possible alternative in the reverse process, by showing the OP how it can be used during the UNPK.
Instead of an MVO, an SRP would work just as well, but that's a more expensive instruction, plus, if you're ultimately unpacking the data, you'd have to reset the sign-nibble after the SRP or the zone-nibble after the UNPK and OR with a X'F'.