Displaying COBOL binary as numeric
Asked Answered
S

4

5

I'm entirely new to COBOL. I have a small COBOL program and a small C file. According to this article: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.1.0/com.ibm.zos.v2r1.ceea400/sdtpt.htm the equivalent of a C signed integer in COBOL is

PIC S9(9) USAGE IS BINARY

I want to call the functions in the C file from COBOL, and display the result in COBOL. I am able to call the function, and it seems to behave as expected, data being passed as expected, but I'm not able to display the binary value with DISPLAY in COBOL.

My COBOL program:

   IDENTIFICATION DIVISION.
   PROGRAM-ID. MSQLTST5_COBHELPER.

   DATA DIVISION.
   WORKING-STORAGE SECTION.
   01 SQLCODE PIC S9(9) USAGE IS BINARY VALUE 100.


   PROCEDURE DIVISION.
   HEAD SECTION.

   MAIN.

       DISPLAY "COBOL, sqlcode is: " SQLCODE.
       CALL "CONNECT_DEFAULT" USING SQLCODE.
       DISPLAY "COBOL, sqlcode is: " SQLCODE.

       STOP RUN.

   END PROGRAM MSQLTST5_COBHELPER.

The C function I'm calling:

void connect_default(int* sqlcode)
{
    printf("C, sqlcode is: %d\n", *sqlcode);
    // internal code that places the expected error code -14006 in the variable sqlcode
    printf("C, sqlcode is: %d\n", *sqlcode);
}

The output of running my COBOL program:

COBOL, sqlcode is: d
C, sqlcode is: 100
C, sqlcode is: -14006
COBOL, sqlcode is: J▒▒▒

It seems that the variable does indeed have the value 100 that I gave it, and then is passed correctly between C and COBOL, but when I ask COBOL to display the variable it seems to try to pick out the character that has the given ASCII code, rather than the numerical value, as the character 'd', which has the ASCII code 100, is displayed rather than the number 100.

How do I display this value as a numeric value in COBOL?

Succubus answered 6/3, 2018 at 8:31 Comment(5)
Can't you transfer the contents of the SQLCODE field to a USAGE DISPLAY field using the MOVE instruction? If you're lucky, it'll convert the binary number to a numeric one.Muns
That does indeed seem to have done something along the lines of what I want, but I'm not sure what is actually displayed. The value 100 is displayed as "00000010{" and the value -14006 is displayed as "00001400O". Perhaps this is just a formatting issue.Succubus
Indeed; my guess is that you used a PIC S9(9) USAGE DISPLAY field, am I correct?Muns
Yes, that is correct, that's how I interpreted your comment.Succubus
Let me add this as an answer.Muns
M
10

Why don't you transfer the contents of the SQLCODE field to a USAGE DISPLAY field using the MOVE instruction? It'll convert the binary number to a numeric one.

If the formatting is strange — here is why:

Signed numeric pictures without the SIGN SEPARATE clause must somehow include the sign without taking up space, so most compilers combine the last digit with the sign of the number. Most conventions use J for −1 till R for −9. They also pad the number with leading zeros. So -14006 will convert to 00001400O, because the last digit is a 6, and because it must be conbined with the minus sign, the last digit becomes -6, which is represented by an O. Roughly the same reasoning counts for 00000010{.

In order to reformat the number, you could actually use another picture, like

pic S9(9) sign leading separate

That will display -14006 as -000014006

Muns answered 6/3, 2018 at 9:11 Comment(4)
That did indeed display it as such, thank you very much for your help!Succubus
As an additional note: as of Enterprise COBOL V5 (I guess - I know for sure it's in V5.2) there's a compile-option DISPSIGN(SEP) that will automatically generate a separate sign for all DISPLAYs of signed numeric items.Unanimous
There is also the difference between COMP/Binary and COMP-5 to consider when the value is set by a non-COBOL program. If this is running on a mainframe there is the TRUNC(BIN) compile option to make all COMP/Binary fields behave as if they are defined as COMP-5.Menam
If you going to be working with interlanguage calls, the book Language Environment Writing Interlanguage Communication Applications (2.3 link) is invaluable. Also, the Enterprise COBOL Programming Guide (6.2 link) has lots of useful information.Gleanings
H
4

This should achieve your intended results.

IDENTIFICATION DIVISION.
PROGRAM-ID. MSQLTST5_COBHELPER.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 SQLCODE PIC S9(9) USAGE IS BINARY VALUE 100.
01 SQLCODE-E PIC -9(9).

PROCEDURE DIVISION.
HEAD SECTION.

MAIN.
    PERFORM DISPLAY-SQLCODE.
    CALL "CONNECT_DEFAULT" USING SQLCODE.
    PERFORM DISPLAY-SQLCODE.

STOP RUN.

DISPLAY-SQLCODE.
    MOVE SQLCODE TO SQLCODE-E.
    DISPLAY "COBOL, sqlcode is: " SQLCODE-E.

END PROGRAM MSQLTST5_COBHELPER.
Hyperplane answered 12/3, 2018 at 17:4 Comment(0)
C
3

The standard way to do this is to move the binary field to a "numeric edited" field:

01 DISPLAY-SQLCODE PIC -(9)9.

Then

MOVE SQLCODE TO DISPLAY-SQLCODE

Full example:

IDENTIFICATION DIVISION.
PROGRAM-ID. MSQLTST5_COBHELPER.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 SQLCODE PIC S9(9) USAGE IS BINARY VALUE 100.
01 DISPLAY-SQLCODE PIC -(9)9.


PROCEDURE DIVISION.
HEAD SECTION.

MAIN.

    MOVE SQLCODE TO DISPLAY-SQLCODE
    DISPLAY "COBOL, sqlcode is: " DISPLAY-SQLCODE
    CALL "CONNECT_DEFAULT" USING SQLCODE
    MOVE SQLCODE TO DISPLAY-SQLCODE
    DISPLAY "COBOL, sqlcode is: " DISPLAY-SQLCODE

    STOP RUN
    .

END PROGRAM MSQLTST5_COBHELPER.
Carillonneur answered 7/3, 2018 at 15:6 Comment(0)
D
0

Move the variable to the display field and then just display the field

01 WS-FIELD-FOR-DISPLAY PIC -(9)9.
Dorm answered 26/6, 2019 at 18:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.