PL/1中有许多不同的数值数据类型。我想知道什么时候有整数,哪里没有。现在,我写了一个小例子,表明(至少对我来说)PL/1 非常纠缠其中:
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);
输出为:
38
34
怎么会是38???我预计34岁,可能是39岁,但肯定不是38岁!! 那么有人可以解释我这个特定的例子有什么问题,当我有整数除法时,当我有整数除法时,什么时候没有? 谢谢。
上级:
编译器的输出:
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
关于您的问题的难点是结果取决于所使用的编译选项(至少对于我们正在使用的Enterprise PL/I 4.5)。
在 RULES(ANS) 下,它按预期使用整数除法,两个表达式的计算结果均为 34。
在 RULES(IBM) 下,它既不使用整数,也不使用浮点除法,而是使用带有比例因子的定点二进制除法!
算术表达式中数据类型转换的完整表可以在这里找到(对于企业PL/I 5.2)。
因此,让我们分析一下使用的数据类型:BIN15
是BIN FIXED(15,0)
,文字11
是DEC FIXED(2,0)
。 根据 RULES(IBM) 下的 PL/I 语言参考,BIN15/11
的结果将是BIN FIXED(31,16)
(假设二进制的最大精度为 31)。
因此,在除法之前,第一个操作数向右移动 16 位,导致十六进制值为26 00 00
。除以 11 得到十六进制03 74 5D
,转换为(大约)3,45454。
乘以 11 得到 37,99994,在加法之前截断为 37。
至于您在PL/I何时使用整数除法而不使用时的最后一个问题: 在 RULES(IBM) 下,PL/I 永远不会使用整数除法。 根据规则(ANS),当两个操作数都未缩放时,PL/I 将使用整数除法FIXED
(即FIXED(x,0)
),其中至少有一个是BINARY
.
作为补充,下面是使用 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)
这里有规则(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)
如果要整数除法,有两种方法:
使用 DIVIDE 内置函数(例如,对于 A/B,写入 除法 (A, B, 31, 0) 如果 B 是十进制的,请使用内置的 BINARY 将其转换为二进制。
以最大的二进制精度声明除数和除数。