You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.

关键修复点说明

  1. SQRT替代方案:用** 0.5实现平方根计算,无需依赖COBOL 2008内置函数,避免编译错误。若坚持使用SQRT,编译时需添加参数:cobc -std=2008 -o program program.cbl。
  2. 几何均值实现:采用对数转换法(GM = exp( (ln(x1)+ln(x2)+...+ln(xn))/n )),彻底避免大数相乘导致的溢出问题,同时增加了正数判断逻辑。
  3. 调和均值实现:新增SUM-HM变量存储倒数和,通过循环累加每个数值的倒数,同时增加了非零判断,防止除以0错误。
  4. 逻辑优化:修正了标准差的计算公式(原代码未减去均值平方,属于样本标准差的错误实现)。

编译与运行

在Linux终端执行以下命令编译运行:

cobc -o stats_program stats_program.cbl
./stats_program

内容的提问来源于stack exchange,提问作者user23756814

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 06:24:54