substract



Support for OS/VS COBOL, VS COBOL II, COBOL for OS/390 & VM and Enterprise COBOL for z/OS

substract

Postby helen2000 » Sun May 24, 2020 1:43 am

Hello,
I got curious result for the following COBOL substract statement:

WS-SUB2                      PIC S9    COMP VALUE ZEROS.
WS-START                    PIC 9(2)  VALUE ZEROES.
WS-END                      PIC 9(2)  VALUE ZEROES.
WS-DIFF                     PIC 9(2)  VALUE ZEROES.

::::::::::::::::::::::::::::::::::::::::::::::::::::::

SUBTRACT WS-START FROM WS-SUB2 GIVING WS-DIFF
:::::::::::::::::::::::::::::::::::::::::::::::::::::
 

when ws-sub2 = +0015 ws-start = 09 the WS-DIFF is 04 instead of 6;
when ws-sub2 = +0016 ws-start = 09 the WS-DIFF is 03 instead of 7;
when ws-sub2 = +0017 ws-start = 09 the WS-DIFF is 02 instead of 8;
when ws-sub2 = +0018 ws-start = 09 the WS-DIFF is 01 instead of 9;
when ws-sub2 = +0019 ws-start = 09 the WS-DIFF is 00 instead of 10;
when ws-sub2 = +0020 ws-start = 09 the WS-DIFF is 09 instead of 11;
when ws-sub2 = +0021 ws-start = 09 the WS-DIFF is 08 instead of 12;
when ws-sub2 = +0022 ws-start = 09 the WS-DIFF is 07 instead of 13;
I dout mybe the datatype caused the issue, could you tell me what's wrong?
thanks for your help,

Helen
helen2000
 
Posts: 85
Joined: Sat Aug 08, 2009 9:44 pm
Has thanked: 0 time
Been thanked: 0 time

Re: substract

Postby enrico-sorichetti » Sun May 24, 2020 2:56 am

a simple
DISPLAY 'WS-SUB2    = ' WS-SUB2

would have made clear the reason
cheers
enrico
When I tell somebody to RTFM or STFW I usually have the page open in another tab/window of my browser,
so that I am sure that the information requested can be reached with a very small effort
enrico-sorichetti
Global moderator
 
Posts: 2994
Joined: Fri Apr 18, 2008 11:25 pm
Has thanked: 0 time
Been thanked: 164 times

Re: substract

Postby helen2000 » Sun May 24, 2020 5:05 am

HI ENRICO,

Thanks for your remind,
this is a online cics cobol program related name displaying, these results number are from my debugging,

when I change the definition to
WS-START pic S9 comp value ZEROS.

the statement "subtract ws-start from ws-sub2 giving ws-diff " will execute properly,


I don't know why " WS-START pic 9(2) value ZEROS" cause the "subtract ws-start from ws-sub2 giving ws-diff" incorrect result,


thanks,

Helen
helen2000
 
Posts: 85
Joined: Sat Aug 08, 2009 9:44 pm
Has thanked: 0 time
Been thanked: 0 time

Re: substract

Postby enrico-sorichetti » Sun May 24, 2020 12:31 pm

WS-SUB2 is defined as S9 which means ONE digit number
How in <heaven> do You expect to store correctly 15, a 2 digit number in a ONE digit

review Your understanding on how cobol handles numeric entities representation
at
https://www.ibm.com/support/knowledgece ... ari02.html
and/or google with "cobol numeric representations"


********************************* Top of Data **********************************
       IDENTIFICATION DIVISION.                                                
       PROGRAM-ID.    Z001 .                                                    
       AUTHOR.        <SOME AUTHOR>                                            
       ENVIRONMENT    DIVISION.                                                
       DATA           DIVISION.                                                
       WORKING-STORAGE SECTION.                                                
       01 SUB1   PIC S9    COMP .                                              
       01 SUB2   PIC S9(2) COMP .                                              
       01 STAR   PIC S9(2) COMP .                                              
       01 DIFF1  PIC S9(2) COMP .                                              
       01 DIFF2  PIC S9(2) COMP .                                              
       PROCEDURE      DIVISION.                                                
           MOVE +15 TO SUB1                                                    
           MOVE +15 TO SUB2                                                    
           MOVE   9 TO STAR                                                    
           DISPLAY 'SUB1    = ' SUB1                                            
           DISPLAY 'SUB2    = ' SUB2                                            
           SUBTRACT STAR FROM SUB1 GIVING DIFF1                                
           SUBTRACT STAR FROM SUB2 GIVING DIFF2                                
           DISPLAY 'DIFF1   = ' DIFF1                                          
           DISPLAY 'DIFF2   = ' DIFF2                                          
           GOBACK.                                                              
******************************** Bottom of Data ********************************
 
cheers
enrico
When I tell somebody to RTFM or STFW I usually have the page open in another tab/window of my browser,
so that I am sure that the information requested can be reached with a very small effort
enrico-sorichetti
Global moderator
 
Posts: 2994
Joined: Fri Apr 18, 2008 11:25 pm
Has thanked: 0 time
Been thanked: 164 times

Re: substract

Postby helen2000 » Sun May 24, 2020 10:19 pm

Hi Enrico,

I follow your sample to write a small program:

IDENTIFICATION DIVISION.
*
PROGRAM-ID. CALC1000.
*
ENVIRONMENT DIVISION.
*
DATA DIVISION.
*
WORKING-STORAGE SECTION.
*
01 DATA-GROUP.
*
     05  SUB                    PIC S9    COMP VALUE ZEROES.
     05  DIFF1                  PIC 9(2)  VALUE ZEROES.
     05  DIFF2                  PIC 9(2)  VALUE ZEROES.
     05  START1                 PIC 9(2)  VALUE ZEROES.
     05  START2                 PIC S9    COMP VALUE ZEROES.

PROCEDURE DIVISION.
*
     MOVE +16 TO SUB
     MOVE   9 TO START1
     MOVE   9 TO START2
     DISPLAY " SUB   = " SUB
     DISPLAY " START1= " START1
     DISPLAY " START2= " START2
     SUBTRACT START1 FROM SUB GIVING DIFF1
     DISPLAY " DIFF1= " DIFF1
     SUBTRACT START2 FROM SUB GIVING DIFF2
     DISPLAY " DIFF2= " DIFF2

    GOBACK
   .
 


this is output:


SUB   = 6
START1= 09
START2= 9
DIFF1= 03
DIFF2= 07
 



my question is: the result DIFF2 is correct, DIFF1 is incorrect, I know the sub is 16 but displaying is 6, furtherly we see:
the result DIFF2 is correct, DIFF1 is incorrect, could someone can explain why?

thanks for your help,
Helen
helen2000
 
Posts: 85
Joined: Sat Aug 08, 2009 9:44 pm
Has thanked: 0 time
Been thanked: 0 time

Re: substract

Postby sergeyken » Sun May 24, 2020 11:55 pm

Case 1.

SUB = 6 ————————— X’C6’
START1= 09 ———————— X’F0F9’
DIFF1 = (SUB - START1) = (+6 - 09) = (-03) = 03 (minus sign lost as per PIC 9(2) -> X’F0F3’)

Case 2.

START2= 9 ———————- X’F9’
DIFF2 = (SUB - START2) = (+6 - 9) = (-3) = 3 (as converted to PIC 9 -> X’F3’)

DIFF2= 07 - should not appear in this example

In general - it is useless and senseless exercise: equivalent to nailing screws using a hammer; much efforts, no output...
Javas and Pythons come and go, but JCL and SORT stay forever.
User avatar
sergeyken
 
Posts: 408
Joined: Wed Jul 24, 2019 10:12 pm
Has thanked: 6 times
Been thanked: 40 times

Re: substract

Postby helen2000 » Mon May 25, 2020 10:44 am

Hi Sergeyken,

my output DIFF2 is exactly 07, I'm confused for the following binary definition:
05  SUB       PIC S9    COMP VALUE ZEROES.

I checked the compiling list, the variable sub took up 2 bytes, at least it can store value from -256 to +255,

in other words, sub can hold +16? something wrong?


thanks for your help:)


Helen
helen2000
 
Posts: 85
Joined: Sat Aug 08, 2009 9:44 pm
Has thanked: 0 time
Been thanked: 0 time

Re: substract

Postby sergeyken » Mon May 25, 2020 7:42 pm

helen2000 wrote:Hi Sergeyken,

my output DIFF2 is exactly 07, I'm confused for the following binary definition:
05  SUB       PIC S9    COMP VALUE ZEROES.

I checked the compiling list, the variable sub took up 2 bytes, at least it can store value from -256 to +255,

in other words, sub can hold +16? something wrong?

Sorry, I missed COMP attribute. Mainly because of bad alignment of source code: reasonable alignment should be
05  SUB       PIC S9 COMP             VALUE ZEROES.

to avoid such misreading of your examples.

If so, this is easier to explain.
Since SUB is actually stored as 2-bytes binary, then everything depends on the “compiler artificial intellect”, and sometimes may be different for various compiler versions(!), and for different platforms.

In case of IBM environment, in physical storage SUB is saved as halfword, and may keep values from -32768 to +32767. All formats (PIC S9 COMP)...(PIC S9999 COMP) are handled in the same way in IBM COBOL.

Initially your SUB is really set to +16

Depending on the second operand in (SUB - STARTx) the real value of SUB is converted either to 1-digit value (e.g. 6), or to 2-digit value (e.g. 16). That’s why the result may be either (-3), or (+7). Next, the sign is ignored, and you get what you see.

As I told at the end of my previous post, these types of experiments are absolutely useless, and mainly senseless. You always need to define all your data in such a way, to allow all expected conversions between them. And also important: not to be lazy, and align your code properly to simplify its understanding, and to avoid misinterpretation by others (and by yourself, after some time has passed!)
Javas and Pythons come and go, but JCL and SORT stay forever.
User avatar
sergeyken
 
Posts: 408
Joined: Wed Jul 24, 2019 10:12 pm
Has thanked: 6 times
Been thanked: 40 times

Re: substract

Postby Terry Heinze » Mon May 25, 2020 10:06 pm

Put simply, if you had defined WS-SUB2 as PIC S9(4) COMP VALUE ZEROS, you would have gotten your expected results. Keep in mind that your SUBTRACT statement is going to drop the sign and give you the absolute value of WS-DIFF.
.... Terry
Terry Heinze
 
Posts: 239
Joined: Wed Dec 04, 2013 11:08 pm
Location: Richfield, MN, USA
Has thanked: 12 times
Been thanked: 11 times

Re: substract

Postby Robert Sample » Tue May 26, 2020 6:00 pm

For binary (COMP) variables, Enterprise COBOL has a compile option called TRUNC which can be BIN, OPT, STD. When TRUNC(BIN) is used, COMP variables can be any valid value; when TRUNC(STD) is used, COMP variables will only be those values allowed by the PICTURE clause (that is, PIC S9 COMP means this variable's values will be between -9 and +9); when TRUNC(OPT) is used the compiler will in some cases use the PICTURE clause and in other cases it will not. COMP variables can only be 2, 4, or 8 bytes long and the number of bytes depends upon the PICTURE clause -- 1 to 4 uses 2 bytes, 5 to 9 uses 4 bytes, 10 to 18 uses 8 bytes.

So defining a variable as S9 COMP and using TRUNC(STD), moving +16 to this variable means you've got a value of +6 since COBOL will ensure the value matches the PICTURE clause. When TRUNC(BIN) is used, the value will be +16. With TRUNC(OPT), who knows?
Robert Sample
Global moderator
 
Posts: 3719
Joined: Sat Dec 19, 2009 8:32 pm
Location: Dubuque, Iowa, USA
Has thanked: 1 time
Been thanked: 279 times

Next

Return to IBM Cobol