10

我有一个非常简单的虚拟 COBOL 程序,它执行虚拟计算并显示结果。

   ID DIVISION.
   PROGRAM-ID. DUMMYPGM.
   DATA DIVISION.
   WORKING-STORAGE SECTION.
   01 NUM-A PIC 9(3) VALUE 399.
   01 NUM-B PIC 9(3) VALUE 211.
   01 NUM-C PIC 9(3).
  *
   PROCEDURE DIVISION.
   MAIN.
       COMPUTE NUM-C = ((NUM-A / 100) - (NUM-B / 100)) * 100
       DISPLAY 'NUM-C IS ' NUM-C
       STOP RUN.

当我在大型机上编译这段代码(使用编译器 MVS Enterprise COBOL V4.2)并执行它时,我得到“NUM-C IS 100”,可能是因为 (399 / 100) 在计算(同样适用于 211 / 100)。

但是当我在 PC 上编译相同的代码(使用 GnuCobol 编译器)并执行它时,我得到“NUM-C IS 188”。PC 的答案是正确的,但我想让它像大型机一样运行(因此,在计算语句中失去精度以给出 100 而不是 188)......我该怎么做?

上面的原因是这段代码的一般表达:

 COMPUTE PDISCR = (((((X(1) + DX - XBRAK) * (ABRAK(1) / 1000)) / 100)
                  + PHT(1) + DPH - PHBRAK) * 2) + ((V(1) + DV 
                  + VBRAKMPM) * (V(1) + DV - VBRAKMPM) / 100000)) 

这是一个有 50 年历史的火车模拟程序的一部分,我需要将其迁移到 GnuCOBOL。COMPUTE 中使用的所有字段都是整数。我需要能够从 GnuCOBOL 得到相同的答案。

已确认 OpenCOBOL/GnuCOBOL 最高 2.0。

4

2 回答 2

2

https://lwn.net/Articles/733129/

此链接提到了 gnuCobol 2.2 的新 std 选项:ibm-strict。我想知道这是否会强制计算语句执行您想要的操作。

于 2019-06-19T21:45:58.393 回答
0

由于看起来 IBM 会截断您的值而 GnuCobol 不会,因此您可能希望使用 GnuCobol 函数来模拟 IBM 的做法。

至少对于正整数,这可能很简单:

COMPUTE NUM-C = ((INTEGER(NUM-A / 100)) - (INTEGER(NUM-B / 100))) * 100

我没有测试这是否适用于负整数,因为 (1) doco 似乎表明它向负无穷大而不是零舍入;(2) 似乎没有TRUNCATE功能;(3) 我假设你不在乎,因为你的数据类型无论如何都没有签名。

如果您确实需要处理负数,可以使用数学方法为您解决问题,我建议您在不同的问题中提出。

于 2018-02-08T08:29:07.697 回答