我该如何进行MOD 97计算

时间:2016-04-08 14:36:24

标签: cobol mainframe

我正在编写一个程序,将国际帐号转换为标准的IBAN结构。

到目前为止,我设法编写了一个程序,用于检查输入的有效性,字符串表示输入在一起而没有嵌入的空格或零,将字母字符转换为与字母表中的位置相对应的数字,并创建带有这些数字的字符串。

现在我所要做的就是计算数字上的Mod 97并从98减去余数。如果结果是一位数,那么我必须插入一个前导零。

我现在拥有的是:

注意:在此步骤之前,我使用指针将数字输入字符串,因此指针(在从中减去1之后)包含字符串的总长度。

WORKING STORAGE SECTION.
01 WORK-FIELDS.
   05  HELP FIELDS.
       10  POINTER                PIC S9(04)           COMP.
       10  DIGITIZED-STRING       PIC X(66).
       10  STRING-FOR-CALCULATION PIC 9(31).

   05  IBAN.
       10 COUNTRY-CODE            PIC X(02).
       10 CHECK-DIGITS            PIC 9(02).
       10 BANK-CODE               PIC X(10).
       10 BRANCH-CODE             PIC X(10).
       10 ACCOUNT-NUMBER          PIC X(28).
       10 OUTPUT-IBAN             PIC X(34). 


PROCEDURE DIVISION.

SUBTRACT 1 FROM POINTER
           STRING DIGITIZED-STRING(1:POINTER)
                  DELIMITED BY SIZE
                  INTO STRING-FOR-CALCULATION
           EVALUATE TRUE
               WHEN POINTER < 32
                    COMPUTE IBAN-CHECK-DIGITS = 98
                    - FUNCTION MOD(STRING-FOR-CALCULATION, 97)
           END-EVALUATE
           .

我有两个问题:

  1. 即使编译器中有ARITH(EXTEND)选项,COBOL也无法处理大于31位的数字字段,我的程序将处理这些字段。我的DIGITIZED-STRING字段长度为66是有原因的。当我编译程序时,我收到此消息:
  2.   

    “由于精度,可能会发生高位数位置的截断   中间结果超过31位。“

    1. 当我的STRING-FOR-CALCULATION字段的长度(如上所示)长于我从DIGITIZED-STRING移动到它的内容时,间隙由尾随零填充。这会影响计算。当我手动将STRING-FOR-CALCULATION字段调整为与DIGITIZED-STRING的内容完全一样长时,计算进展顺利。
    2. 我只是不知道如何在我处理更短和更长的数字时确保它有效,我必须将其分成几部分。

      其他信息:

      我正在使用此文档作为指南:www.bpfi.ie/wp-content/uploads/2014/10/MOD-97-Final-May-2013.pdf

      但我不知道如何在COBOL中执行此操作。

      此外,对于那些善意阅读和回答我之前的问题的人来说,这些领域不是国家的原因是因为我的项目经理改变了他的想法。现在,我所要做的就是使用MOVE FUNCTION NATIONAL-OF将IBAN-OUTPUT字段移动到副本。

      更新

      我正在使用COBOL / 390编译器。

      以下是我最终使用的代码:

      WORKING-STORAGE SECTION.
      
      01   DIGITIZED-STRING                  PIC X(66).
      01   POINTER                           PIC S9(04)           COMP.
      
      01   TEST-FIELDS.
                  05  VERY-LONG-NUMBER.
                      10  VLN-FIRST-PART     PIC 9(11).
                      10  VLN-SECOND-PART    PIC 9(11).
                      10  VLN-THIRD-PART     PIC 9(11).
                      10  VLN-FOURTH-PART    PIC 9(11).
                      10  VLN-FIFTH-PART     PIC 9(11).
                      10  VLN-SIXTH-PART     PIC 9(11).
                  05  EXPANDED-DIVIDEND                    PIC 9(13).
                  05  FILLER
                      REDEFINES EXPANDED-DIVIDEND.
                      10  ED-REMAINDER                     PIC 99.
                      10  ED-PART                          PIC 9(11).
                  05  IRRELEVANT-ANSWER                    PIC 9(12).
      
      
      
      PROCEDURE DIVISION.
      MOVE SPACES TO TEST-FIELDS
                 MOVE ZEROES TO TEST-FLDS
                 MOVE DIGITIZED-STRING(1:POINTER)
                      TO VERY-LONG-NUMBER(66 - POINTER + 1:POINTER)
      
                     MOVE ZERO                    TO ED-REMAINDER
                     MOVE VLN-FIRST-PART          TO ED-PART
                     DIVIDE EXPANDED-DIVIDEND     BY 97
                       GIVING                     IRRELEVANT-ANSWER
                       REMAINDER                  ED-REMAINDER
                     MOVE VLN-SECOND-PART         TO ED-PART
                     DIVIDE EXPANDED-DIVIDEND     BY 97
                       GIVING                       IRRELEVANT-ANSWER
                       REMAINDER                    ED-REMAINDER
                     MOVE VLN-THIRD-PART          TO ED-PART
                     DIVIDE EXPANDED-DIVIDEND     BY 97
                       GIVING                       IRRELEVANT-ANSWER
                       REMAINDER                    ED-REMAINDER
                     MOVE VLN-FOURTH-PART         TO ED-PART
                     DIVIDE EXPANDED-DIVIDEND     BY 97
                       GIVING                       IRRELEVANT-ANSWER
                       REMAINDER                    ED-REMAINDER
                     MOVE VLN-FIFTH-PART         TO ED-PART
                     DIVIDE EXPANDED-DIVIDEND     BY 97
                       GIVING                       IRRELEVANT-ANSWER
                       REMAINDER                    ED-REMAINDER
                     MOVE VLN-SIXTH-PART         TO ED-PART
                     DIVIDE EXPANDED-DIVIDEND     BY 97
                       GIVING                       IRRELEVANT-ANSWER
                       REMAINDER                    ED-REMAINDER
      
                 COMPUTE CHECK-DIGITS = 98
                         - ED-REMAINDER
                 .
      

1 个答案:

答案 0 :(得分:4)

你喜欢“长师”。

1234 divided by 97 =
123 divided by 97, which gives x (doesn't matter for you) remainder 26
264 divided by 97, gives x, remainder 70

70是1234的mod 97。

这是一个示例程序:

   ID DIVISION. 
   PROGRAM-ID. STAB22. 
   DATA DIVISION. 
   WORKING-STORAGE SECTION. 
   01  VERY-LONG-NUMBER                     PIC 9(8). 
   01  FILLER 
       REDEFINES VERY-LONG-NUMBER. 
       05  VLN-FIRST-PART                   PIC 9(4). 
       05  VLN-SECOND-PART                  PIC 9(4). 
   01  EXPANDED-DIVIDEND                    PIC 9(6). 
   01  FILLER 
       REDEFINES EXPANDED-DIVIDEND. 
       05  ED-REMAINDER                     PIC 99. 
       05  ED-PART                          PIC 9(4). 
   01  IRRELEVANT-ANSWER                    PIC 9(5). 
   01  VALUE-FOR-MOD-97      PACKED-DECIMAL PIC 99 VALUE 97.
   PROCEDURE DIVISION. 
       MOVE 1234                    TO VERY-LONG-NUMBER 
       MOVE ZERO                    TO ED-REMAINDER 
       MOVE VLN-FIRST-PART          TO ED-PART 
       DIVIDE EXPANDED-DIVIDEND     BY VALUE-FOR-MOD-97 
         GIVING                     IRRELEVANT-ANSWER 
         REMAINDER                  ED-REMAINDER 
       MOVE VLN-SECOND-PART         TO ED-PART 
       DIVIDE EXPANDED-DIVIDEND     BY VALUE-FOR-MOD-97 
         GIVING                     IRRELEVANT-ANSWER 
         REMAINDER                  ED-REMAINDER 
       DISPLAY ED-REMAINDER 
       MOVE 12345678                TO VERY-LONG-NUMBER 
       MOVE ZERO                    TO ED-REMAINDER 
       MOVE VLN-FIRST-PART          TO ED-PART 
       DIVIDE EXPANDED-DIVIDEND     BY VALUE-FOR-MOD-97 
         GIVING                     IRRELEVANT-ANSWER 
         REMAINDER                  ED-REMAINDER 
       MOVE VLN-SECOND-PART         TO ED-PART 
       DIVIDE EXPANDED-DIVIDEND     BY VALUE-FOR-MOD-97 
         GIVING                     IRRELEVANT-ANSWER 
         REMAINDER                  ED-REMAINDER 
       DISPLAY ED-REMAINDER 
       GOBACK 
       . 

结果为70和03。

你推断。我建议你有11位数的六个部分,每次都有13位数的红利。使用编译器选项ARITH(EXTEND),这比使用更少的代码尝试使用更长的数字更有效。