我有这个cobol程序,意在计算一个阶乘:
IDENTIFICATION DIVISION.
PROGRAM-ID. Factorial-hopefully.
AUTHOR. Darth Egregious.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 Keeping-Track-Variables.
05 Operand PIC S99 VALUE 0.
05 Product PIC S99 VALUE 1.
PROCEDURE DIVISION.
PERFORM-FACTORIAL.
DISPLAY SPACES
PERFORM VARYING Operand FROM 6 BY -1 UNTIL Operand = 0
DISPLAY "Before Product " Product " Operand " Operand
MULTIPLY Product By Operand GIVING Product
DISPLAY "After Product " Product " Operand " Operand
END-PERFORM
DISPLAY Product.
STOP RUN.
我这样运行:
cobc -free -x -o a.out fact.cbl && ./a.out
我得到了这个奇怪的输出:
Before Product +01 Operand +06
After Product +06 Operand +06
Before Product +06 Operand +05
After Product +30 Operand +05
Before Product +30 Operand +04
After Product +30 Operand +04
Before Product +30 Operand +03
After Product +90 Operand +03
Before Product +90 Operand +02
After Product +90 Operand +02
Before Product +90 Operand +01
After Product +90 Operand +01
+90
我的递减循环按预期工作,但MULTIPLY
命令行为奇怪。它正确地执行1*6
和6*5
,但30*4
似乎无效,然后30*3
执行,最后90*2
不再工作了。 COBOL不喜欢乘以2或2的幂吗?
答案 0 :(得分:7)
我的递减循环按预期工作,但MULTIPLY命令的行为很奇怪。它正确地做了1 * 6和6 * 5,但30 * 4似乎不起作用,然后30 * 3,但最终90 * 2不再起作用。 COBOL不喜欢乘以2或2的幂吗?
05 Operand PIC S99 VALUE 0.
05 Product PIC S99 VALUE 1.
当您将30*4
和90*2
相乘时,这些值会大于PICTURE
子句S99
。
将PIC
子句的大小增加到S999
。
对评论的回应:
从技术上讲,结果是未定义的[COBOL 85
],因此什么都不做是一个有效的选择。其他实现将截断该值,从而产生不同的结果。
所以它不是语言,而是实现。
该语言还允许SIZE ERROR
短语捕获截断错误。在这种情况下,结果不会改变,但可能会执行其他代码来指示错误发生。
使用COBOL 2002
,如果未指定ON SIZE ERROR
短语且检查EC-SIZE-TRUNCATION
异常未激活,则结果由实现者定义。
引自2002年标准:
F.1可能影响现有计划的实质性变化
15)没有SIZE ERROR短语的大小错误条件。如果出现大小错误情况,则发生它的语句不包含SIZE ERROR或NOT SIZE ERROR短语,并且没有关联的声明,实现者定义运行单元是终止还是继续执行不正确的值。
理由:
在之前的COBOL标准中,大小错误的规则声明执行将继续使用未定义的值,但不清楚执行将继续的位置,特别是在条件语句中。此外,对于许多关键应用程序而言,继续执行不正确的结果是不可接受的,因为它可能导致数据库损坏,程序的错误继续执行以及潜在的大量其他错误。修改程序以禁止为每个受影响的语句添加ON SIZE ERROR是令人望而却步的。为响应用户需求,一些实现者在这种情况下终止了程序的执行;在某些情况下,实现者允许基于编译器指令选择终止。
在这种情况下终止的应用程序的数量和关键性为此更改提供了强有力的理由。预计此更改对现有程序的影响不大,因为实现者可以根据以前的COBOL标准的实现自由继续或终止。