有没有办法在我的 COBOL 程序中更好地管理我的数据使用

KD *_*Fer 0 memory cobol

我目前正在编写一个程序,可以在 COBOL 中找到最大的质因数或一个数字。这是我所拥有的:

IDENTIFICATION DIVISION.
PROGRAM-ID. EULER2.
DATA DIVISION.
WORKING-STORAGE SECTION.
    01 num1 PIC 9(12) VALUE 600851475143.
    01 num2 PIC 9(6) VALUE 2.
    01 smallest PIC 9(6) VALUE 0. 
    01 num3 PIC 9(6). 
PROCEDURE DIVISION.
MAIN-PROCEDURE. 

PERFORM whileLoop UNTIL num1 <= num2.
DISPLAY "Greatest prime of large number " smallest. 
STOP RUN.

whileLoop.
    IF FUNCTION MOD(num1, num2) = 0
        DIVIDE num2 INTO num1.
        IF(smallest LESS THAN num2)
            SET smallest TO num2
            ADD 1 TO smallest
    ELSE
        ADD 1 TO num2
    END-IF.  
Run Code Online (Sandbox Code Playgroud)

此代码有效。但是为了得到正确的答案,我必须将 1 添加到最小,因为它会返回小于 1 的最大素数。此外,当我检查诸如最小之类的东西时,输出比我运行这个要多得多另一种语言的程序。我想知道这里是否存在内存问题,或者我是否可以深入了解 COBOL 如何运行它。

Ric*_*ith 5

没有内存使用问题。运行时间受使用显示值而不是二进制值(我使用过comp-5)的影响,并且所有偶数都经过测试,尽管这些不是可能的素数。

正如最初编写的那样,循环在 时终止num1 <= num2。添加1到后num2num2变为等于num1,但smallest值小于 1 num1。通过将循环终止更改为num1 < num2,最终值保存在smallest. 这消除了添加最终1.

在代码中,我添加了语句来显示num2. 显示的数字是原始数字的主要因素。我还将声明之后的所有分隔符都替换为段落末尾的单独一行。

我更改以解决评论和其他问题。

如果num1是素数或有一个因数,其中要么给出超过 6 位的结果,则会出现溢出,num2这将导致“除以零”异常。也就是说,PICTUREfor的子句num2永远不能小于for的子句num1。我将PICTURE子句设为 18 位,在大多数情况下,将是 64 位。

我添加了一些显示格式以使其“更整洁”。

我把SET声明改成了MOVE声明。请注意,SET在 1985 和 2002 标准中,使用语句在两个数字数据项之间进行赋值都是语法错误。

ISO/IEC 1989:2002
SET 语句
14.8.35.2 语法规则
4) 如果 identifier-1 引用数字数据项,则应指定 index-name-2。

其他更改地址速度。num2检查2,然后检查奇数3及以上。当num2大于 的平方根时,终止对下一个因子的搜索num1。最大的 18 位质数999,999,999,999,999,991可能仍然需要几分钟,但比没有这些变化快大约 10 亿倍。

代码:

   IDENTIFICATION DIVISION.
   PROGRAM-ID. EULER2.
   DATA DIVISION.
   WORKING-STORAGE SECTION.
   01 num1 comp-5 PIC S9(18) VALUE 600851475143.
   01 num2 comp-5 PIC S9(18) VALUE 2.
   01 smallest comp-5 PIC S9(18) VALUE 1.
   01 temp comp-5 PIC S9(18).
   01 rem comp-5 PIC S9(18).
   01 sqrt-num1 comp-5 PIC S9(18).
   01 num-display PIC BZZZ,ZZZ,ZZZ,ZZZ,ZZZ,ZZ9.
   01 trimmed-display PIC X(23).
   PROCEDURE DIVISION.
   MAIN-PROCEDURE. 
       PERFORM get-sqrt-num1
       DISPLAY "Factors:"
       PERFORM whileLoop UNTIL num1 < num2
       MOVE smallest TO num-display
       PERFORM trim-num
       DISPLAY SPACE
       DISPLAY "Greatest prime of large number: "
           trimmed-display
       STOP RUN
       .

   whileLoop.
       DIVIDE num2 INTO num1 GIVING temp REMAINDER rem
       IF rem = 0
           MOVE temp TO num1
           PERFORM get-sqrt-num1
           IF(smallest LESS THAN num2)
               MOVE num2 TO smallest
           end-if
           MOVE num2 TO num-display
           PERFORM trim-num
           DISPLAY trimmed-display
       ELSE
           IF num2 > 2
               ADD 2 TO num2
           ELSE
               ADD 1 TO num2
           END-IF
           IF num2 > sqrt-num1
               MOVE num1 TO num2
           END-IF
       END-IF
       .

   get-sqrt-num1.
       COMPUTE sqrt-num1 = FUNCTION SQRT (num1)
       .

   trim-num.
       UNSTRING num-display DELIMITED ALL SPACE
           INTO trimmed-display (1:1) trimmed-display
       .
Run Code Online (Sandbox Code Playgroud)

输出:

Factors:
71
839
1,471
6,857

Greatest prime of large number: 6,857
Run Code Online (Sandbox Code Playgroud)