Cobol,寻找百分比

时间:2014-09-17 22:23:07

标签: cobol

我正在为我的课程完成一项作业,而我在获取百分比以显示COBOL实验室的正确价值方面存在问题。

我的问题是PERCENT-DISCOUNT / WS-PERCENT-WITH-DISCOUNT(至少,我相信它是)。

当程序运行时,我得到结果50.0。我应该得到的结果(假设我手动正确地进行了数学运算)是55.6。我不太确定我哪里出错了。

以下是我目前为该计划编写的代码。

  *
   IDENTIFICATION DIVISION.
   PROGRAM-ID. LAB2.
   AUTHOR. XXXXXXX XXXXXXXXXXX.

  *
   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.

       SELECT IPT-FILE ASSIGN TO 'LAB2.DAT'
           ORGANIZATION IS LINE SEQUENTIAL.

       SELECT PRT-FILE ASSIGN TO 'LAB2_OUTPUT.DAT'
           ORGANIZATION IS LINE SEQUENTIAL.

  *
   DATA DIVISION.
   FILE SECTION.

  *
   FD IPT-FILE
       RECORD CONTAINS 80 CHARACTERS
       RECORDING MODE IS F
       DATA RECORD IS INPUT-RECORD.

   01 IPT-RECORD.
       05 IPT-INV-NUMBER       PIC 9(04).
       05 IPT-INV-QUANTITY     PIC 9(03).
       05 IPT-INV-DESCRIPTION  PIC X(13).
       05 IPT-INV-UNITPRICE    PIC 9999V99.
       05 IPT-INV-PROD-CLASS   PIC 9(01).

  *
   FD PRT-FILE
       RECORD CONTAINS 132 CHARACTERS
       RECORDING MODE IS F
       DATA RECORD IS PRT-LINE.

   01 PRT-LINE.
       05 FILLER               PIC X(04).
       05 PRT-INV-NUMBER       PIC 9(04).
       05 FILLER               PIC X(02).
       05 PRT-EXTENDED-PRICE   PIC Z,ZZZ,ZZ9.99.
       05 FILLER               PIC X(04).
       05 PRT-DISCOUNT-AMOUNT  PIC ZZZ,ZZ9.99.
       05 FILLER               PIC X(03).
       05 PRT-NET-PRICE        PIC Z,ZZZ,ZZ9.99.
       05 FILLER               PIC X(10).
       05 PRT-PRODUCT-CLASS    PIC 9.
       05 FILLER               PIC X(07).
       05 PRT-TRANS-PERCENT    PIC Z9.9.
       05 FILLER               PIC X(05).
       05 PRT-TRANS-CHARGE     PIC ZZZ,ZZ9.99.

  *
   WORKING-STORAGE SECTION.
  *
   01 EOF-SWITCH               PIC X VALUE 'N'.

  *
   01 WS-EXTENDED-COST         PIC 9(07)V99.

   01 WS-DISCOUNT-AMOUNT       PIC 9(06)V99.

   01 WS-NET-COST              PIC 9(07)V99.

   01 WS-TRANS-PERCENT         PIC ZZ9V9.

   01 WS-TRANS-COST            PIC 9(06)V99.

  *
   01 WS-TOTAL-EXTENDED-COST   PIC 9(09)V99 VALUE ZERO.

   01 WS-TOTAL-NET-COST        PIC 9(08)V99 VALUE ZERO.

   01 WS-TOTAL-TRANS-COST      PIC 9(08)V99 VALUE ZERO.

   01 WS-TOTAL-WITH-DISCOUNT   PIC 99V9 VALUE ZERO.

   01 WS-TOTAL-ITEMS           PIC 99V9 VALUE ZERO.

   01 WS-PERCENT-WITH-DISCOUNT PIC 99V9.

   01 WS-TOTAL-NO-DISCOUNT     PIC 99V9 VALUE ZERO.

  *
   01 HEADING-NAME.
       05 MY-NAME              PIC X(20) VALUE
           'XXXXX XXXXXXX, LAB 2'.

   01 HEADING-COLUMN-1.
       05 FILLER               PIC X(05) VALUE SPACES.
       05 COLUMN-1-INV-NUM     PIC X(03) VALUE 'INV'.
       05 FILLER               PIC X(06) VALUE SPACES.
       05 COLUMN-1-EXT-PRC     PIC X(08) VALUE 'EXTENDED'.
       05 FILLER               PIC X(06) VALUE SPACES.
       05 COLUMN-1-DISC-AMT    PIC X(08) VALUE 'DISCOUNT'.
       05 FILLER               PIC X(06) VALUE SPACES.
       05 COLUMN-1-NET-PRC     PIC X(09) VALUE 'NET PRICE'.
       05 FILLER               PIC X(06) VALUE SPACES.
       05 COLUMN-1-CLASS       PIC X(05) VALUE 'CLASS'.
       05 FILLER               PIC X(06) VALUE SPACES.
       05 COLUMN-1-TRANS-P     PIC X(05) VALUE 'TRANS'.
       05 FILLER               PIC X(06) VALUE SPACES.
       05 COLUMN-1-TRANS-C     PIC X(14) VALUE 'TRANSPORTATION'.

   01 HEADING-COLUMN-2.
       05 FILLER               PIC X(05) VALUE SPACES.
       05 COLUMN-2-INV-NUM     PIC X(03) VALUE 'NUM'.
       05 FILLER               PIC X(09) VALUE SPACES.
       05 COLUMN-2-EXT-PRC     PIC X(08) VALUE 'PRICE'.
       05 FILLER               PIC X(05) VALUE SPACES.
       05 COLUMN-2-DISC-AMT    PIC X(08) VALUE 'AMOUNT'.
       05 FILLER               PIC X(06) VALUE SPACES.
       05 COLUMN-2-NET-PRC     PIC X(09) VALUE SPACES.
       05 FILLER               PIC X(06) VALUE SPACES.
       05 COLUMN-2-CLASS       PIC X(05) VALUE SPACES.
       05 FILLER               PIC X(08) VALUE SPACES.
       05 COLUMN-2-TRANS-P     PIC X(05) VALUE '%'.
       05 FILLER               PIC X(05) VALUE SPACES.
       05 COLUMN-2-TRANS-C     PIC X(14) VALUE 'CHARGE'.

   01 BLANK-LINE.
       05  BLANK-SPACE         PIC X VALUE SPACES.

   01 TOTAL-FOOTER.
       05 FILLER               PIC X(07) VALUE SPACES.
       05 TOTAL-EXTENDED-COST  PIC $$$$,$$$,$$9.99.
       05 FILLER               PIC X(15) VALUE SPACES.
       05 TOTAL-NET-COST       PIC $$$,$$$,$$9.99.
       05 FILLER               PIC X(23) VALUE SPACES.
       05 TOTAL-TRANS-COST     PIC $$$,$$$,$$9.99.

   01 TOTAL-NO-DISCOUNT-FOOTER.
       05 TOTAL-SENTENCE       PIC X(31) VALUE
           'TOTAL ITEMS WITHOUT DISCOUNT = '.
       05 TOTAL-NO-DISCOUNT    PIC Z9.

   01 PERCENT-DISCOUNT-FOOTER.
       05 PERCENT-SENTENCE     PIC X(44) VALUE
           'PERCENT OF ITEMS THAT RECEIVED A DISCOUNT = '.
       05 PERCENT-DISCOUNT     PIC Z9.9.

  *
   PROCEDURE DIVISION.
  *
       OPEN INPUT IPT-FILE.
       OPEN OUTPUT PRT-FILE.

  *
       WRITE PRT-LINE FROM HEADING-NAME AFTER ADVANCING 0 LINES.
       WRITE PRT-LINE FROM HEADING-COLUMN-1 AFTER ADVANCING 3 LINES.
       WRITE PRT-LINE FROM HEADING-COLUMN-2 AFTER ADVANCING 1 LINES.
       WRITE PRT-LINE FROM BLANK-LINE AFTER ADVANCING 1 LINES.

  *
       READ IPT-FILE AT END MOVE 'Y' TO EOF-SWITCH.

  *
       PERFORM MAIN-LOOP UNTIL EOF-SWITCH EQUALS 'Y'.

  *
       DIVIDE WS-TOTAL-WITH-DISCOUNT BY WS-TOTAL-ITEMS
           GIVING WS-PERCENT-WITH-DISCOUNT.

       MULTIPLY WS-PERCENT-WITH-DISCOUNT BY 100
           GIVING WS-PERCENT-WITH-DISCOUNT.

  *
       MOVE WS-TOTAL-EXTENDED-COST TO TOTAL-EXTENDED-COST.
       MOVE WS-TOTAL-NET-COST TO TOTAL-NET-COST.
       MOVE WS-TOTAL-TRANS-COST TO TOTAL-TRANS-COST.
       MOVE WS-TOTAL-NO-DISCOUNT TO TOTAL-NO-DISCOUNT.
       MOVE WS-PERCENT-WITH-DISCOUNT TO PERCENT-DISCOUNT.

  *
       WRITE PRT-LINE FROM TOTAL-FOOTER AFTER ADVANCING 3 LINES.
       WRITE PRT-LINE FROM TOTAL-NO-DISCOUNT-FOOTER AFTER
           ADVANCING 3 LINES.
       WRITE PRT-LINE FROM BLANK-LINE AFTER ADVANCING 1 LINES.
       WRITE PRT-LINE FROM PERCENT-DISCOUNT-FOOTER AFTER ADVANCING
           1 LINES.

  *
       CLOSE IPT-FILE, PRT-FILE.
       STOP RUN.

  *
   MAIN-LOOP.

       MOVE SPACES TO PRT-LINE.

  *
       MULTIPLY IPT-INV-QUANTITY BY IPT-INV-UNITPRICE
           GIVING WS-EXTENDED-COST ROUNDED.
       MOVE WS-EXTENDED-COST TO PRT-EXTENDED-PRICE.

  *
       ADD 1 TO WS-TOTAL-ITEMS

  *
       IF WS-EXTENDED-COST IS GREATER THAN 200 THEN
           MULTIPLY WS-EXTENDED-COST BY 0.11 GIVING
               WS-DISCOUNT-AMOUNT ROUNDED

           ADD 1 TO WS-TOTAL-WITH-DISCOUNT
  *
       ELSE
           MOVE ZERO TO WS-DISCOUNT-AMOUNT

           ADD 1 TO WS-TOTAL-NO-DISCOUNT

       END-IF.

  *
       IF IPT-INV-PROD-CLASS IS EQUAL TO 1 THEN
           MOVE 27.0 TO WS-TRANS-PERCENT

           MULTIPLY WS-EXTENDED-COST BY 0.27 GIVING
               WS-TRANS-COST ROUNDED
  *
       ELSE IF IPT-INV-PROD-CLASS IS EQUAL TO 2 THEN
           MOVE 17.0 TO WS-TRANS-PERCENT

           MULTIPLY WS-EXTENDED-COST BY 0.17 GIVING
               WS-TRANS-COST ROUNDED
  *
       ELSE IF IPT-INV-QUANTITY IS GREATER THAN 100 THEN
           MOVE 13.5 TO WS-TRANS-PERCENT

           MULTIPLY WS-EXTENDED-COST BY 0.135 GIVING
               WS-TRANS-COST ROUNDED
  *
       ELSE
           MOVE ZERO TO WS-TRANS-PERCENT
           MOVE 25.00 TO WS-TRANS-COST

       END-IF.

  *
       SUBTRACT WS-EXTENDED-COST FROM WS-DISCOUNT-AMOUNT
           GIVING WS-NET-COST.

       ADD WS-EXTENDED-COST TO WS-TOTAL-EXTENDED-COST.
       ADD WS-NET-COST TO WS-TOTAL-NET-COST.
       ADD WS-TRANS-COST TO WS-TOTAL-TRANS-COST.


  *
       MOVE IPT-INV-NUMBER TO PRT-INV-NUMBER.
       MOVE WS-EXTENDED-COST TO PRT-EXTENDED-PRICE.
       MOVE WS-DISCOUNT-AMOUNT TO PRT-DISCOUNT-AMOUNT.
       MOVE WS-NET-COST TO PRT-NET-PRICE.
       MOVE IPT-INV-PROD-CLASS TO PRT-PRODUCT-CLASS.
       MOVE WS-TRANS-PERCENT TO PRT-TRANS-PERCENT.
       MOVE WS-TRANS-COST TO PRT-TRANS-CHARGE.

  *
       WRITE PRT-LINE AFTER ADVANCING 1 LINES.

  *
       READ IPT-FILE AT END MOVE 'Y' TO EOF-SWITCH.

以下是.dat文件保存的信息。

2047105TYPEWRITER   0800002
1742010HANDLE       0010001
2149150USB DRIVE    1200003
3761005TAPE         5000004
2791010BOLTS        0000751
3000100STAPLER      0002007
3001101OVERHEAD PROJ0099997
3002099PENCILS      0000097
4001184CANADIAN RUGS0150294
4003050CARPET       0040000
4005001WASTE BASKETS0003793
5001010HINGES       0010001
5003010PENS (GOLD)  0049992
5004400PENS (BLACK) 0002004
8888999HIGH CHAIR   9999991
8889412PLAY PEN     0074992
0001001LOW TEST     0000019
9999999LAST RECORD  0000011

1 个答案:

答案 0 :(得分:6)

你的问题在这里:

01 WS-PERCENT-WITH-DISCOUNT PIC 99V9.

当您进行除法时,将结果存储在该字段中。如果你期望它是0.556,你存储的是0.5,因为你只定义了一个小数位,所以两个低位小数位被简单地截断。

当你乘以100时,你得到50.0。

如果您定义具有三个小数位的字段,则应显示您的预期答案(我没有检查您的数据)。

然而,更好的方法是定义更多整数位,以便该字段足够大以容纳中间结果并先乘以100 。然后你可以划分(你可能想考虑ROUNDED,但这取决于程序的规范)。

此处有一些关于COMPUTE问题的问题。阅读这些问题并理解答案将有助于您掌握这些问题。在COBOL中,定义所需的准确度,并通过提供正确数量的整数和小数位来实现。

您还可以查看其他一些COBOL问题,在这些问题中,您可以找到有关在文件上使用FILE STATUS以及检查每个IO的结果的大量建议。您还可以使用您定义的文件状态字段来检查文件结尾,而不是使用AT END/NOT AT END:您应该发现它需要更少的代码,并且更容易理解。

尽可能多地完全停止/停止。在PROCEDURE DIVISION标题的末尾需要一个,一个在过程名称的末尾,一个在过程的末尾,一个在程序的末尾(如果没有过程名称) 。所有其他都是多余的。代码中的逗号往往会分散注意力,您可能会发现使用缩进和语句格式更清晰。

虽然构造良好,但您的嵌套 - IF会更好EVALUATE

你的程序中有很多常量。最好将它们定义为具有良好选择名称的数据项,以便代码“读取”,并且没有人不得不怀疑0.27的重要性。你也有一些例子,你有两个明显相关的常数,例如27.0和0.27,只需要做一件事就可以得到更好的服务。如果某人“维护”了该程序,他们可能只会更改其中一个值而不会更改另一个值(不要期望有另一个值)。

另请参阅使用88级条件名称。例如,“switch = y”可以成为“发票结束文件”,而88可以是该文件的文件状态,值为“10”。

您应该使用空输入文件测试您的程序,看看您是否喜欢这些结果。

作为COBOL的初学者,它根本不是一个糟糕的镜头。