GnuCOBOL 3.1.2程序添加GM、HM、RMS功能报错求助
问题解决与功能实现指导
核心问题说明
SQRT未定义:GnuCOBOL 3.1.2默认未启用COBOL 2008标准的内置数学函数,需通过编译参数开启,或用幂运算** 0.5替代。- 语法错误:代码中直接写
X(1)*X(2)*...*X(N)、1/X(1)+...属于无效语法,需通过循环实现累加/累乘。 - 数值溢出风险:几何均值的累乘操作容易超出普通PIC变量的范围,建议用对数转换法规避。
修正后的代码实现(包含RMS、调和均值、几何均值)
以下是修复后的完整代码,解决了上述所有问题:
IDENTIFICATION DIVISION. PROGRAM-ID. FileProcessingProgram. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT INPUT-FILE ASSIGN TO 'nums.txt'. SELECT OUTPUT-FILE ASSIGN TO 'output.txt'. DATA DIVISION. FILE SECTION. FD INPUT-FILE. 01 INPUT-VALUE-RECORD. 02 IN-X PIC S9(6)V9(2). 02 FILLER PIC X(72). FD OUTPUT-FILE. 01 OUTPUT-LINE PIC X(80). WORKING-STORAGE SECTION. 77 SUM-OF-X-SQR PIC 9(14)V9(2). 77 SUM-OF-X PIC S9(10)V9(2). 77 N PIC S9(4). 77 MEAN PIC S9(6)V9(2). 77 I PIC S9(4). 77 SUM-HM PIC S9(10)V9(4). *> 存储调和均值的倒数和 77 LOG-SUM-GM PIC S9(6)V9(6). *> 存储几何均值的对数和(规避溢出) 01 ARRAY-AREA. 02 X PIC S9(6)V9(2) OCCURS 1000 TIMES. 01 OUTPUT-TITLE-LINE. 02 FILLER PIC X(35) VALUE " MEAN, DEVIATION AND STATISTICS". 01 OUTPUT-UNDERLINE. 02 FILLER PIC X(35) VALUE "-----------------------------------". 01 OUTPUT-COL-HEADS. 02 FILLER PIC X(10) VALUE SPACES. 02 FILLER PIC X(11) VALUE "DATA VALUES". 01 OUTPUT-DATA-LINE. 02 FILLER PIC X(10) VALUE SPACES. 02 OUT-X PIC -(6)9.9(2). 01 OUTPUT-RESULTS-LINE-1. 02 FILLER PIC X(9) VALUE " MEAN= ". 02 OUT-MEAN PIC -(6)9.9(2). 01 OUTPUT-RESULTS-LINE-2. 02 FILLER PIC X(9) VALUE " STD DEV=". 02 STD-DEVIATION PIC -(6)9.9(2). 01 OUTPUT-RESULTS-LINE-3. 02 FILLER PIC X(9) VALUE " GEOMETRIC MEAN=". 02 GEOMETRIC-MEAN PIC -(6)9.9(2). 01 OUTPUT-RESULTS-LINE-4. 02 FILLER PIC X(9) VALUE " HARMONIC MEAN=". 02 HARMONIC-MEAN PIC -(6)9.9(2). 01 OUTPUT-RESULTS-LINE-5. 02 FILLER PIC X(9) VALUE " ROOT MEAN SQ=". 02 ROOT-MEAN-SQUARE PIC -(6)9.9(2). PROCEDURE DIVISION. OPEN INPUT INPUT-FILE, OUTPUT OUTPUT-FILE. MOVE ZERO TO IN-X. PERFORM PROC-BODY UNTIL IN-X IS NOT LESS THAN 999999.99. PERFORM END-OF-JOB. PROC-BODY. WRITE OUTPUT-LINE FROM OUTPUT-TITLE-LINE AFTER ADVANCING 0 LINES. WRITE OUTPUT-LINE FROM OUTPUT-UNDERLINE AFTER ADVANCING 1 LINE. WRITE OUTPUT-LINE FROM OUTPUT-COL-HEADS AFTER ADVANCING 1 LINE. WRITE OUTPUT-LINE FROM OUTPUT-UNDERLINE AFTER ADVANCING 1 LINE. MOVE ZERO TO SUM-OF-X, SUM-HM, LOG-SUM-GM. READ INPUT-FILE INTO INPUT-VALUE-RECORD AT END PERFORM END-OF-JOB. PERFORM INPUT-LOOP VARYING N FROM 1 BY 1 UNTIL N IS GREATER THAN 1000 OR IN-X IS NOT LESS THAN 999999.98. SUBTRACT 1 FROM N. * 计算均值 DIVIDE N INTO SUM-OF-X GIVING MEAN ROUNDED. * 计算平方和(用于标准差、RMS) MOVE ZERO TO SUM-OF-X-SQR. PERFORM SUM-LOOP VARYING I FROM 1 BY 1 UNTIL I IS GREATER THAN N. * 计算标准差 COMPUTE STD-DEVIATION ROUNDED = (SUM-OF-X-SQR / N - MEAN * MEAN) ** 0.5. * 计算几何均值(对数转换法避免溢出) PERFORM GM-LOOP VARYING I FROM 1 BY 1 UNTIL I IS GREATER THAN N. COMPUTE GEOMETRIC-MEAN ROUNDED = EXP(LOG-SUM-GM / N). * 计算调和均值 PERFORM HM-LOOP VARYING I FROM 1 BY 1 UNTIL I IS GREATER THAN N. COMPUTE HARMONIC-MEAN ROUNDED = N / SUM-HM. * 计算均方根(用幂运算替代SQRT) COMPUTE ROOT-MEAN-SQUARE ROUNDED = (SUM-OF-X-SQR / N) ** 0.5. * 输出结果 WRITE OUTPUT-LINE FROM OUTPUT-UNDERLINE AFTER ADVANCING 1 LINE. MOVE MEAN TO OUT-MEAN. WRITE OUTPUT-LINE FROM OUTPUT-RESULTS-LINE-1 AFTER ADVANCING 1 LINE. WRITE OUTPUT-LINE FROM OUTPUT-RESULTS-LINE-2 AFTER ADVANCING 1 LINE. WRITE OUTPUT-LINE FROM OUTPUT-RESULTS-LINE-3 AFTER ADVANCING 1 LINE. WRITE OUTPUT-LINE FROM OUTPUT-RESULTS-LINE-4 AFTER ADVANCING 1 LINE. WRITE OUTPUT-LINE FROM OUTPUT-RESULTS-LINE-5 AFTER ADVANCING 1 LINE. INPUT-LOOP. MOVE IN-X TO X(N), OUT-X. WRITE OUTPUT-LINE FROM OUTPUT-DATA-LINE AFTER ADVANCING 1 LINE. ADD X(N) TO SUM-OF-X. READ INPUT-FILE INTO INPUT-VALUE-RECORD AT END PERFORM END-OF-JOB. SUM-LOOP. COMPUTE SUM-OF-X-SQR = SUM-OF-X-SQR + (X(I) * X(I)). GM-LOOP. * 几何均值仅适用于正数,跳过非正值 IF X(I) > 0 THEN COMPUTE LOG-SUM-GM = LOG-SUM-GM + LOG(X(I)) END-IF. HM-LOOP. * 避免除以0错误 IF X(I) NOT = 0 THEN COMPUTE SUM-HM = SUM-HM + (1 / X(I)) END-IF. END-OF-JOB. CLOSE INPUT-FILE, OUTPUT-FILE. STOP RUN.
关键修复点说明
SQRT替代方案:用** 0.5实现平方根计算,无需依赖COBOL 2008内置函数,避免编译错误。若坚持使用SQRT,编译时需添加参数:cobc -std=2008 -o program program.cbl。- 几何均值实现:采用对数转换法(
GM = exp( (ln(x1)+ln(x2)+...+ln(xn))/n )),彻底避免大数相乘导致的溢出问题,同时增加了正数判断逻辑。 - 调和均值实现:新增
SUM-HM变量存储倒数和,通过循环累加每个数值的倒数,同时增加了非零判断,防止除以0错误。 - 逻辑优化:修正了标准差的计算公式(原代码未减去均值平方,属于样本标准差的错误实现)。
编译与运行
在Linux终端执行以下命令编译运行:
cobc -o stats_program stats_program.cbl ./stats_program
内容的提问来源于stack exchange,提问作者user23756814
相关产品推荐
相关产品推荐

