我目前正在编写一个程序,可以在 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 如何运行它。
没有内存使用问题。运行时间受使用显示值而不是二进制值(我使用过comp-5
)的影响,并且所有偶数都经过测试,尽管这些不是可能的素数。
正如最初编写的那样,循环在 时终止num1 <= num2
。添加1
到后num2
,num2
变为等于num1
,但smallest
值小于 1 num1
。通过将循环终止更改为num1 < num2
,最终值保存在smallest
. 这消除了添加最终1
.
在代码中,我添加了语句来显示num2
. 显示的数字是原始数字的主要因素。我还将声明之后的所有分隔符都替换为段落末尾的单独一行。
我更改以解决评论和其他问题。
如果num1
是素数或有一个因数,其中要么给出超过 6 位的结果,则会出现溢出,num2
这将导致“除以零”异常。也就是说,PICTURE
for的子句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)
归档时间: |
|
查看次数: |
73 次 |
最近记录: |