COBOL计算

COBOL计算,cobol,Cobol,我正在执行一个独立的企业COBOL程序,计算如下。我有一个计算与多个操作和另一个与完整的计算分裂。但两种情况下的结果都不同(最后4位) 我已经使用计算器手动计算了这些,结果与split-up-COMPUTE语句匹配。我在中间结果中使用了整个答案,只使用了最终答案的15位数字,在所有中间步骤中也只使用了15位数字(没有舍入)。但这些结果都与综合计算结果不符 有人能帮我理解为什么会有这样的差异吗 05 WS-A PIC S9(3)V9(15) COMP.

我正在执行一个独立的企业COBOL程序,计算如下。我有一个计算与多个操作和另一个与完整的计算分裂。但两种情况下的结果都不同(最后4位)

我已经使用计算器手动计算了这些,结果与split-up-COMPUTE语句匹配。我在中间结果中使用了整个答案,只使用了最终答案的15位数字,在所有中间步骤中也只使用了15位数字(没有舍入)。但这些结果都与综合计算结果不符

有人能帮我理解为什么会有这样的差异吗

      05 WS-A              PIC S9(3)V9(15) COMP.
      05 WS-B              PIC S9(3)V9(15) COMP.
      05 WS-C              PIC S9(3)V9(15) COMP.
      05 WS-D              PIC S9(3)V9(15) COMP.
      05 WS-E              PIC S9(3)V9(15) COMP.
      05 WS-RES            PIC S9(3)V9(15) COMP.  
      05 RES-DISP          PIC -9(2).9(16).

       MOVE 3.56784                TO WS-A.
       MOVE 1.3243284234           TO WS-B.
       MOVE .231433897121334834    TO WS-C.
       MOVE 9.3243243213           TO WS-D.
       MOVE 7.0                    TO WS-E.   

       COMPUTE WS-RES = WS-A / WS-B.
       MOVE WS-RES TO RES-DISP.
       COMPUTE WS-RES = WS-RES / WS-C.
       MOVE WS-RES TO RES-DISP.   
       COMPUTE WS-RES = WS-RES / (WS-D + WS-E).
       MOVE WS-RES TO RES-DISP.   
       COMPUTE WS-RES = WS-RES * (WS-C - WS-A) 
       MOVE WS-RES TO RES-DISP.   
       COMPUTE WS-RES = WS-RES + WS-E ** WS-B 
       MOVE WS-RES TO RES-DISP.   
       COMPUTE WS-RES = WS-RES + WS-D.
       MOVE WS-RES TO RES-DISP.   
上次计算结果=20.1030727225138740

       COMPUTE WS-RES = WS-A / WS-B / WS-C /
               (WS-D + WS-E) * (WS-C - WS-A) +
               WS-E ** WS-B + WS-D.
       MOVE WS-RES TO RES-DISP.   

组合计算的结果=20.1030727225138680,我知道,速度很慢,但我想我已经明白了为什么你用15位小数定义了所有东西。否则你无法让它工作

阅读下面链接中的问题(当然还有答案)。您不需要以输出所需的精度指定所有字段

重新安排你的计算。主计算之外的求幂运算。先乘。然后分开。任何加减法都很自然。使用括号精确地指定您希望人工读取计算的方式(编译器不在乎,它会按照指示执行,但有时人们不知道他们在告诉它什么)

如果您这样做(正确),您将得到与计算中相同的答案,所有字段都有15位小数

如果您不这样做,您的计算(以及您复制它时的其他计算)将始终是脆弱的,并且在更改时容易出错

这是一个很好的主意,把计算分成更小的部分,就像你做的那样,这样你就可以看到哪些值要输入到你的计算器中。当您将字段设置为正确的大小时,也可以执行相同的操作

我将不得不完全重写这篇文章,因为多次更新使它变得混乱。。。在某个时刻

好的,确认了。差异是由于计算中的非整数幂运算,如手册所述,然后将计算中的所有内容(所有中间字段)转换为浮点数,其小数位数高于PICture子句中指定的15位

由于乘法运算,现在有一条诊断消息(去掉了求幂运算),它希望有36位数字,但只能有30位(ARITH(COMPAT))或31位(ARITH(EXTEND))。如果通过此操作截断高阶数据,则会出现运行时消息

注意。对于算术运算(COMPAT),15是不会丢失精度的最大有效位数(64位浮点)。ARITH(EXTEND)保证精度,但在处理过程中会有开销(128位浮点)

回到早些时候

我一直在思考这个问题。您使用的是18位数字,您没有提到使用ARITH(EXTEND)作为编译选项,也没有提到为大型计算机生成的任何诊断消息。这很有趣

在COBOL中没有做太多的求幂运算,然后只使用整数。所以我看了手册。由于分数幂运算,大型计算机中的所有操作都是以浮点运算完成的。这本身并不重要,但这意味着事情正在以比你定义的15位小数更高的精度进行。在您的小型计算机中,这不会发生

我建议从大计算中取出指数,单独计算,然后简单地将结果放入大计算中(一个简单的加法代替指数)。我怀疑在那个阶段,编译器会开始抱怨结果中的有效位数。如果真的丢失了一个有效数字,那么您将收到一条运行时消息

你应该:

  • 从大型计算中取出求幂运算,并将其替换为单独计算求幂运算的结果
  • 将每个字段定义为数据所需的最大大小(不是所有字段的最大值)
  • (可能)从COMP更改为COMP-3,但自己测试
  • 插入所有内容,以便人类读者知道编译器将按什么顺序进行操作
  • 如果您仍然有关于计算中可能的截断的警告,请查看ARITH(EXTEND)编译器选项,但不要只是将其作为修复,只在需要时使用它,并记录它在该程序中的使用
  • 我稍后会尝试确认这一点,但我认为这会解决问题

    以下是开始,并且仍然适用于一般情况,尽管与具体问题没有直接关系(问题是强制对所有对象使用更高的浮点精度,而不是仅强制进行求幂):

    小计算的问题在于,它们的执行顺序与大计算的元素不同

    不是为了好玩,也不是为了把事情组合在一起,它们在计算中建立了优先级

    还有什么可以确立优先权?接线员用了一个电话。优先顺序是什么?嗯,你必须在手册中查找,记住它,或者每次忘记时都要熟悉它。嗯。。。。这不是个好建议

    另外,其他人也会为你编写或修改的程序工作。他们可能“知道”计算机是如何工作的(我的意思是他们不知道,但认为他们知道,所以不会去查)。这是一个非常不好的建议

    所以

    使用
    并定义完成任务的顺序

    同时也要注意你可能失去的意义。看看这一部分,阅读并理解企业COBOL手册的参考部分

    总结
      COMPUTE WS-EXP = WS-E ** WS-B 
      COMPUTE WS-RES = WS-A / WS-B / WS-C /  
         (WS-D + WS-E) * (WS-C - WS-A) +  
         WS-EXP + WS-D.
    
    IGYPG3113-W Truncation of high-order digit positions may occur due to intermediate results exceeding 30 digits