There are so many different numeric data types in PL/1. And I want to know when there is an integer devision, and where is not. For instant, I've written a small example that shows (at least for me) that PL/1 is very entangled in it:
DCL BIN15 FIXED BIN(15) INIT(38);
DCL BIN31 FIXED BIN(31) INIT(38);
BIN15=BIN15/11*11+1;
PUT SKIP LIST(BIN15);
BIN31=BIN31/11*11+1;
PUT SKIP LIST(BIN31);
Output is:
38
34
How it even can be 38??? I've expected 34, may be 39, but defenetly not 38!!! So can somebody explain me what is wrong with this particular example, and in a whole when I have integer division, and when not? Thanks.
UPD:
Compiler's output:
15655-H31 IBM(R) Enterprise PL/I for z/OS V3.R4.M0 (Built:20050114) 2018.01.12 12:21:31 Page 1
- Options Specified
0 Install:
0 Command: MACRO,S,X,A,AG,LC(64),MAP,LANGLVL(SPROG),NOF,,LIST
0 Install:
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) 2018.01.12 12:21:31 Page 2
0 Compiler Source
0 Line.File
0 1.1 /*process rules(nolaxdcl); */
2.1 MAINP:PROC OPTIONS(MAIN);
3.1
4.1 DCL BIN15 FIXED BIN(15) INIT(38);
5.1 DCL BIN31 FIXED BIN(31) INIT(38);
6.1 BIN15=BIN15/11*11+1;
7.1 PUT SKIP LIST(BIN15);
8.1 BIN31=BIN31/11*11+1;
9.1 PUT SKIP LIST(BIN31);
10.1
11.1 END MAINP;
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) 2018.01.12 12:21:31 Page 3
- Attribute/Xref Table
- Line.File Identifier Attributes
0 4.1 BIN15 AUTOMATIC FIXED BIN(15,0) INITIAL
Refs: 6.1 7.1
Sets: 6.1
5.1 BIN31 AUTOMATIC FIXED BIN(31,0) INITIAL
Refs: 8.1 9.1
Sets: 8.1
2.1 MAINP CONSTANT EXTERNAL
ENTRY()
+++++++ SYSPRINT CONSTANT EXTERNAL FILE STREAM
OUTPUT PRINT
Refs: 7.1 9.1
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) 2018.01.12 12:21:31 Page 4
- Block Name List
0 Number Name
0 1 MAINP
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) 2018.01.12 12:21:31 Page 5
OFFSET OBJECT CODE LINE# FILE# P S E U D O A S S E M B L Y L I S T I N G
Timestamp and Version Information
000000 F2F0 F1F8 =C'2018' Compiled Year
000004 F0F1 F1F2 =C'0112' Compiled Date MMDD
000008 F1F2 F2F1 F3F1 =C'122131' Compiled Time HHMMSS
00000E F0F3 F0F4 F0F0 =C'030400' Compiler Version
000014 0028 **** Service String
Timestamp and Version End
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) : MAINP 2018.01.12 12:21:31 Page 6
OFFSET OBJECT CODE LINE# FILE# P S E U D O A S S E M B L Y L I S T I N G
000000 000002 | MAINP DS 0D
000000 47F0 F022 000002 | B 34(,r15)
000004 01C3C5C5 CEE eyecatcher
000008 00000140 DSA size
00000C 00000200 =A(PPA1-MAINP)
000010 47F0 F001 000002 | B 1(,r15)
000014 58F0 C31C 000002 | L r15,796(,r12)
000018 184E 000002 | LR r4,r14
00001A 05EF 000002 | BALR r14,r15
00001C 00000000 =F'0'
000020 07F3 000002 | BR r3
000022 90E7 D00C 000002 | STM r14,r7,12(r13)
000026 58E0 D04C 000002 | L r14,76(,r13)
00002A 4100 E140 000002 | LA r0,320(,r14)
00002E 5500 C314 000002 | CL r0,788(,r12)
000032 4130 F03A 000002 | LA r3,58(,r15)
000036 4720 F014 000002 | BH 20(,r15)
00003A 58F0 C280 000002 | L r15,640(,r12)
00003E 90F0 E048 000002 | STM r15,r0,72(r14)
000042 9210 E000 000002 | MVI 0(r14),16
000046 50D0 E004 000002 | ST r13,4(,r14)
00004A 18DE 000002 | LR r13,r14
00004C End of Prolog
00004C 5860 3192 000002 | L r6,=A(**MAINP2)(,r3,402)
000050 5870 3196 000000 | L r7,=A(@CONSTANT_AREA)(,r3,406)
000054 4100 0000 000002 | LA r0,0
000058 5000 D0A8 000002 | ST r0,_Sfi(,r13,168)
00005C 5000 D0AC 000002 | ST r0,_Sfi(,r13,172)
000060 5810 3186 000002 | L r1,=F'1573248'
000064 5010 D0B0 000002 | ST r1,_Sfi(,r13,176)
000068 5000 D0BC 000002 | ST r0,_Sfi(,r13,188)
00006C 1806 000002 | LR r0,r6
00006E 5000 6008 000002 | ST r0,_Pfo_4(,r6,8)
000072 4100 0026 000002 | LA r0,38
000076 5000 D0A4 000002 | ST r0,BIN31(,r13,164)
00007A 4000 D0A0 000002 | STH r0,BIN15(,r13,160)
00007E 4840 D0A0 000006 | LH r4,BIN15(,r13,160)
000082 8940 0010 000006 | SLL r4,16
000086 8E40 0020 000006 | SRDA r4,32
00008A 5D40 318A 000006 | D r4,=F'11'
00008E 1805 000006 | LR r0,r5
000090 A70C 000B 000006 | MHI r0,H'11'
000094 5E00 318E 000006 | AL r0,=F'65536'
000098 5000 D138 000006 | ST r0,_temp3(,r13,312)
00009C 1810 000006 | LR r1,r0
00009E 8A10 001F 000006 | SRA r1,31
0000A2 8810 0010 000006 | SRL r1,16
0000A6 1E01 000006 | ALR r0,r1
0000A8 8A00 0010 000006 | SRA r0,16
0000AC 8900 0010 000006 | SLL r0,16
0000B0 8A00 0010 000006 | SRA r0,16
0000B4 4000 D0A0 000006 | STH r0,BIN15(,r13,160)
0000B8 4100 D0C0 000007 | LA r0,_temp1(,r13,192)
0000BC 5000 D130 000007 | ST r0,_temp2(,r13,304)
0000C0 A748 4A48 000007 | LHI r4,H'19016'
0000C4 4040 D0EC 000007 | STH r4,_temp1(,r13,236)
0000C8 5800 6004 000007 | L r0,SYSPRINT(,r6,4)
0000CC 5000 D12C 000007 | ST r0,_temp2(,r13,300)
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) : MAINP 2018.01.12 12:21:31 Page 7
OFFSET OBJECT CODE LINE# FILE# P S E U D O A S S E M B L Y L I S T I N G
0000D0 4120 0001 000007 | LA r2,1
0000D4 5020 D0C0 000007 | ST r2,_temp1(,r13,192)
0000D8 4100 D128 000007 | LA r0,_temp2(,r13,296)
0000DC 58F0 319A 000007 | L r15,=V(IBMQOFNT)(,r3,410)
0000E0 4110 D098 000007 | LA r1,#MX_TEMP1(,r13,152)
0000E4 5000 D098 000007 | ST r0,#MX_TEMP1(,r13,152)
0000E8 05EF 000007 | BALR r14,r15
0000EA 4100 7014 000007 | LA r0,'....'(,r7,20)
0000EE 5000 D0D8 000007 | ST r0,_temp1(,r13,216)
0000F2 4100 D0A0 000007 | LA r0,BIN15(,r13,160)
0000F6 5000 D0D4 000007 | ST r0,_temp1(,r13,212)
0000FA 9220 D0EE 000007 | MVI _temp1(r13,238),32
0000FE 4100 D128 000007 | LA r0,_temp2(,r13,296)
000102 58F0 319E 000007 | L r15,=V(IBMQOFPT)(,r3,414)
000106 4110 D098 000007 | LA r1,#MX_TEMP1(,r13,152)
00010A 5000 D098 000007 | ST r0,#MX_TEMP1(,r13,152)
00010E 05EF 000007 | BALR r14,r15
000110 9201 D0EE 000007 | MVI _temp1(r13,238),1
000114 4100 D128 000007 | LA r0,_temp2(,r13,296)
000118 58F0 319E 000007 | L r15,=V(IBMQOFPT)(,r3,414)
00011C 4110 D098 000007 | LA r1,#MX_TEMP1(,r13,152)
000120 5000 D098 000007 | ST r0,#MX_TEMP1(,r13,152)
000124 05EF 000007 | BALR r14,r15
000126 1814 000007 | LR r1,r4
000128 1802 000007 | LR r0,r2
00012A 5840 D0A4 000008 | L r4,BIN31(,r13,164)
00012E 8E40 0020 000008 | SRDA r4,32
000132 5D40 318A 000008 | D r4,=F'11'
000136 1825 000008 | LR r2,r5
000138 A72C 000B 000008 | MHI r2,H'11'
00013C A72A 0001 000008 | AHI r2,H'1'
000140 5020 D0A4 000008 | ST r2,BIN31(,r13,164)
000144 4120 D0C0 000009 | LA r2,_temp1(,r13,192)
000148 5020 D130 000009 | ST r2,_temp2(,r13,304)
00014C 4010 D0EC 000009 | STH r1,_temp1(,r13,236)
000150 5810 6004 000009 | L r1,SYSPRINT(,r6,4)
000154 5010 D12C 000009 | ST r1,_temp2(,r13,300)
000158 5000 D0C0 000009 | ST r0,_temp1(,r13,192)
00015C 4100 D128 000009 | LA r0,_temp2(,r13,296)
000160 58F0 319A 000009 | L r15,=V(IBMQOFNT)(,r3,410)
000164 4110 D098 000009 | LA r1,#MX_TEMP1(,r13,152)
000168 5000 D098 000009 | ST r0,#MX_TEMP1(,r13,152)
00016C 05EF 000009 | BALR r14,r15
00016E 4100 7018 000009 | LA r0,'....'(,r7,24)
000172 5000 D0D8 000009 | ST r0,_temp1(,r13,216)
000176 4100 D0A4 000009 | LA r0,BIN31(,r13,164)
00017A 5000 D0D4 000009 | ST r0,_temp1(,r13,212)
00017E 9220 D0EE 000009 | MVI _temp1(r13,238),32
000182 4100 D128 000009 | LA r0,_temp2(,r13,296)
000186 58F0 319E 000009 | L r15,=V(IBMQOFPT)(,r3,414)
00018A 4110 D098 000009 | LA r1,#MX_TEMP1(,r13,152)
00018E 5000 D098 000009 | ST r0,#MX_TEMP1(,r13,152)
000192 05EF 000009 | BALR r14,r15
000194 9201 D0EE 000009 | MVI _temp1(r13,238),1
000198 4100 D128 000009 | LA r0,_temp2(,r13,296)
00019C 58F0 319E 000009 | L r15,=V(IBMQOFPT)(,r3,414)
0001A0 4110 D098 000009 | LA r1,#MX_TEMP1(,r13,152)
0001A4 5000 D098 000009 | ST r0,#MX_TEMP1(,r13,152)
0001A8 05EF 000009 | BALR r14,r15
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) : MAINP 2018.01.12 12:21:31 Page 8
OFFSET OBJECT CODE LINE# FILE# P S E U D O A S S E M B L Y L I S T I N G
0001AA 000011 | @1L1 DS 0H
0001AA 58F0 31A2 000011 | L r15,=V(IBMQEFSH)(,r3,418)
0001AE 05EF 000011 | BALR r14,r15
0001B0 000011 | @1L2 DS 0H
0001B0 Start of Epilog
0001B0 58D0 D004 000011 | L r13,4(,r13)
0001B4 58E0 D00C 000011 | L r14,12(,r13)
0001B8 9827 D01C 000011 | LM r2,r7,28(r13)
0001BC 051E 000011 | BALR r1,r14
0001BE 0707 000011 | NOPR 7
0001C0 Start of Literals
0001C0 00180180 =F'1573248'
0001C4 0000000B =F'11'
0001C8 00010000 =F'65536'
0001CC 00000000 =A(**MAINP2)
0001D0 00000220 =A(@CONSTANT_AREA)
0001D4 00000000 =V(IBMQOFNT)
0001D8 00000000 =V(IBMQOFPT)
0001DC 00000000 =V(IBMQEFSH)
0001E0 End of Literals
*** General purpose registers used: 1111111100001111
*** Floating point registers used: 1111111100000000
*** Size of register spill area: 512(max) 0(used)
*** Size of dynamic storage: 320
*** Size of executable code: 448
*** CSECT Offset: 64 : 0x40
Constant Area
000000 0008E2E8 E2D7D9C9 D5E30000 0005D4C1 |..SYSPRINT....MA|
000010 C9D5D700 00000F80 00001F80 |INP......... |
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) 2018.01.12 12:21:31 Page 9
OFFSET OBJECT CODE LINE# FILE# P S E U D O A S S E M B L Y L I S T I N G
PPA1: Entry Point Constants
000000 1CCEA166 =F'483303782' Flags
000004 00000240 =A(PPA2-MAINP)
000008 00000000 =F'0' No PPA3
00000C 00000000 =F'0' No EPD
000010 FFC00000 =F'-4194304' Register save mask
000014 40000000 =F'1073741824' Member flags
000018 90 =AL1(144) Flags
000019 000000 =AL3(0) Callee's DSA use/8
00001C 0040 =H'64' Flags
00001E 0012 =H'18' Offset/2 to CDL
000020 D00000A8 =F'-805306200' State variable location
000024 500000E0 =F'1342177504' CDL function length/2
000028 FFFFFE00 =F'-512' CDL function EP offset
00002C 38260000 =F'942014464' CDL prolog
000030 400800D8 =F'1074266328' CDL epilog
000034 00000000 =F'0' CDL end
000038 0005 **** AL2(5),C'MAINP'
PPA1 End
PPA2: Compile Unit Block
000000 0B00 3203 =F'184562179' Flags
000004 FFFF FD80 =A(CEESTART-PPA2)
000008 0000 0000 =F'0' No PPA4
00000C FFFF FD80 =A(TIMESTMP-PPA2)
000010 0000 0000 =F'0' No primary
000014 0200 0000 =F'33554432' Flags
PPA2 End
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) 2018.01.12 12:21:31 Page 10
E X T E R N A L S Y M B O L D I C T I O N A R Y
NAME TYPE ID ADDR LENGTH NAME TYPE ID ADDR LENGTH
**MAINP1 SD 1 000000 000298 **MAINP2 SD 2 000000 000058
MAINP LD 0 000040 000001 CEESG011 ER 3 000000
IBMQOFNT ER 4 000000 IBMQOFPT ER 5 000000
IBMQEFSH ER 6 000000 CEESTART ER 7 000000
IBMPOFCX ER 8 000000 CEEMAIN SD 9 000000 00000C
IBMPINPL ER 10 000000 MAINP ER 11 000000
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) 2018.01.12 12:21:31 Page 11
E X T E R N A L S Y M B O L C R O S S R E F E R E N C E
ORIGINAL NAME EXTERNAL SYMBOL NAME
**MAINP1 **MAINP1
**MAINP2 **MAINP2
MAINP MAINP
CEESG011 CEESG011
IBMQOFNT IBMQOFNT
IBMQOFPT IBMQOFPT
IBMQEFSH IBMQEFSH
CEESTART CEESTART
IBMPOFCX IBMPOFCX
CEEMAIN CEEMAIN
IBMPINPL IBMPINPL
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) 2018.01.12 12:21:31 Page 12
* * * * * S T O R A G E O F F S E T L I S T I N G * * * * *
IDENTIFIER DEFINITION ATTRIBUTES
<SEQNBR>-<FILE NO>:<FILE LINE NO>
BIN15 1-1:4 Class = automatic, Location = 160 : 0xA0(r13), Length = 2
BIN31 1-1:5 Class = automatic, Location = 164 : 0xA4(r13), Length = 4
* * * * * E N D O F S T O R A G E O F F S E T L I S T I N G * * * * *
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) 2018.01.12 12:21:31 Page 13
* * * * * S T A T I C M A P * * * * *
OFFSET (HEX) LENGTH (HEX) NAME
0 4 _Anchor_4
4 4 SYSPRINT
8 18 _Pfo_4
20 38 _Sib
* * * * * E N D O F S T A T I C M A P * * * * *
* * * * * E N D O F C O M P I L A T I O N * * * * *
15655-H31 IBM(R) Enterprise PL/I for z/OS /*process rules(nolaxdcl) 2018.01.12 12:21:31 Page 14
- File Reference Table
0 File Included From Name
0 1 SHCHER.TEST.PLI(FIRST1)
- Component Return Code Messages (Total/Suppressed) Time
0 MACRO 0 0 / 0 0 secs
Compiler 0 1 / 1 1 secs
0 End of compilation of MAINP
The difficult point about your question is that the results depend on the compile-options used (at least with Enterprise PL/I 4.5 which we are using).
Under RULES(ANS) it is using integer-division as expected and both expressions evaluate to 34.
Under RULES(IBM) it is using neither integer nor floating-point division but fixed-point binary division with a scale factor!
The full table of datatype-conversions in arithmetic expressions can be found here (for Enterprise PL/I 5.2).
So let's analyze the datatypes used:
BIN15
is BIN FIXED(15,0)
and the literal 11
is DEC FIXED(2,0)
.
According to the PL/I Language Reference under RULES(IBM) the result for BIN15/11
will be BIN FIXED(31,16)
(assuming the maximum precision for binary is 31).
So before division the first operand is shifted right by 16 bits resulting in a hex-value of 26 00 00
. Division by 11 results in hex 03 74 5D
which converts to (approximately) 3,45454.
Multiplying by 11 results in 37,99994 which is truncated to 37 before the addition.
As for your finaly question when PL/I is using integer-division and when not:
Under RULES(IBM) PL/I will never use integer-division.
Under RULES(ANS) PL/I will use integer-division when both operands are unscaled FIXED
(i.e. FIXED(x,0)
) and at least one of them is BINARY
.
As an addition, here is the assembly-code generated with RULES(IBM):
4800 D0C0 000007 ! LH r0,BIN15(,r13,192)
EB40 0010 00DF 000007 ! SLLK r4,r0,16
8E40 0020 000007 ! SRDA r4,32
4100 000B 000007 ! LA r0,11
1D40 000007 ! DR r4,r0
1805 000007 ! LR r0,r5
A70C 000B 000007 ! MHI r0,H'11'
C20B 0001 0000 000007 ! ALFI r0,F'65536'
5000 D164 000007 ! ST r0,_temp5(,r13,356)
EB10 001F 00DC 000007 ! SRAK r1,r0,31
8810 0010 000007 ! SRL r1,16
1E01 000007 ! ALR r0,r1
8A00 0010 000007 ! SRA r0,16
B927 0000 000007 ! LHR r0,r0
4000 D0C0 000007 ! STH r0,BIN15(,r13,192)
and here with RULES(ANS):
4840 D0C0 000007 ! LH r4,BIN15(,r13,192)
8E40 0020 000007 ! SRDA r4,32
4100 000B 000007 ! LA r0,11
1D40 000007 ! DR r4,r0
1805 000007 ! LR r0,r5
B927 0000 000007 ! LHR r0,r0
A70C 000B 000007 ! MHI r0,H'11'
A70A 0001 000007 ! AHI r0,H'1'
B927 0000 000007 ! LHR r0,r0
4000 D0C0 000007 ! STH r0,BIN15(,r13,192)