COBOL对位(bit)进行操作

记得有人说过COBOL不能对位进行操作,可能是某位师兄。其实想一下还是可以的,只不过麻烦了点。

 

一、先说一下思路:

   1.操作的对象是BYTE A(使用工具程序BITTOOL能改变其中8位任意一位的值)。首先把A的每一位的值(0或1)

   保存到一个8BYTE的B的每一个BYTE上。然后改变你想要改变的地方。最后根据B得到结果的一个BYTE的C。

 

   2.两个重点是从一个BYTE的八个BYTE的转换和从八个BYTE到一个BYTE的转换。从一个BYTE的八个BYTE的转换:

  如果A大于等于128(10000000),则第一位是‘1’,否则为‘0’;A减去128,如果A大于等于64(01000000),

  则第二位是‘1’,否则为‘0’ ;如此类推。

 

代码:

BIT-TO-BYTES.                                                   

     MOVE 0                 TO WK-HWORD-BINARY                   

     MOVE 1                 TO WK-IX                             

     MOVE 128               TO WK-FACTOR                         

     MOVE BTS-PASS-BIT      TO WK-HWORD-02                       

     PERFORM 8 TIMES                                             

        IF WK-HWORD-BINARY = WK-FACTOR                           

        OR WK-HWORD-BINARY > WK-FACTOR THEN                      

           MOVE '1'         TO BTS-PASS-BYTES(WK-IX:1)           

           COMPUTE WK-HWORD-BINARY = WK-HWORD-BINARY             

                                   - WK-FACTOR                   

        ELSE                                                     

           MOVE '0'         TO BTS-PASS-BYTES(WK-IX:1)           

        END-IF                                                   

        COMPUTE WK-FACTOR = WK-FACTOR / 2                        

        COMPUTE WK-IX     = WK-IX + 1                            

     END-PERFORM                                                 

     .                                                           

BIT-TO-BYTES-EXIT.                                              

     EXIT.    

 

   3.从八个BYTE到一个BYTE的转换:如果B的第一个BYTE是1,C加上128(10000000),否则什么都不做;

   如果B的第二个BYTE是1,C加上64(01000000),否则什么都不做;如此类推。

 

代码:

BYTES-TO-BIT.                                                  

    MOVE 0                 TO WK-HWORD-BINARY                  

    MOVE 1                 TO WK-IX                            

    MOVE 128               TO WK-FACTOR                        

    PERFORM 8 TIMES                                            

        IF  BTS-PASS-BYTES(WK-IX:1) = '1'                      

            COMPUTE WK-HWORD-BINARY = WK-HWORD-BINARY          

                                    + WK-FACTOR                

        ELSE                                                   

            IF  BTS-PASS-BYTES(WK-IX:1) NOT = '0'              

               DISPLAY '8-BYTE STRING MUST BE ZEROES OR ONES...'

               ADD 8       TO WK-IX                            

               ADD 8       TO BTS-PASS-RESULT                  

            END-IF                                             

        END-IF                                                 

        COMPUTE WK-FACTOR  = WK-FACTOR / 2                      

        COMPUTE WK-IX      = WK-IX + 1                          

    END-PERFORM                                                 

    MOVE WK-HWORD-02       TO BTS-PASS-BIT                      

    .                                                           

BYTES-TO-BIT-EXIT.                                              

    EXIT. 

 

二、下面是完整的代码,已测试通过,包括CALL时用到的COPYBOOK(CPBIT),工具程序BITTOOL,测试程序BITTEST。

 

CPBIT:

*===============================================================*
*   INTERFACE FOR BIT PROCESS                                   *
*             BY ICESCUT FOR TEST                               *
*===============================================================*
01  BTS-PASS-AREA.                                             
     05  BTS-PASS-REQUEST            PIC X(1).                  
         88  BTS-PASS-TOBYTES        VALUE 'Y'.                 
         88  BTS-PASS-TOBIT          VALUE 'I'.                 
     05  BTS-PASS-RESULT             PIC S9(9)   BINARY.        
         88  BTS-PASS-SUCCESS        VALUE 0.                   
     05  BTS-PASS-RECORD.                                       
         10  BTS-PASS-BIT            PIC X.                     
         10  BTS-PASS-BYTES          PIC X(8).                  

 

BTS-PASS-REQUEST是一个FLAG,指示进行转换为BYTES还是BITS。

 

BITTOOL:

IDENTIFICATION  DIVISION.                                       

PROGRAM-ID.     BITTOOL.                                        

******************************************************************

*                     BIT CONVERSION TOOL                        *

*                        BY ICESCUT                              *

******************************************************************

ENVIRONMENT     DIVISION.                                       

DATA            DIVISION.                                       

WORKING-STORAGE SECTION.                                        

01  WK-AREA.                                                    

     05  WK-HWORD.                                               

         10  WK-HWORD-01        PIC X.                           

         10  WK-HWORD-02        PIC X.                           

     05  WK-HWORD-BINARY        REDEFINES      WK-HWORD          

                                PIC S9(4)      BINARY.           

     05  WK-IX                  PIC 99         VALUE 1.          

     05  WK-FACTOR              PIC S9(5)      VALUE 128.        

     05  WK-TEXT                PIC X(80).                       

LINKAGE         SECTION.                                        

*<<  LINK AREA   >>*                                             

COPY CPBIT.                                                     

PROCEDURE       DIVISION USING BTS-PASS-AREA.                   

*-----------------------------------------------------------------

* MAIN ROUTINE                                                   

*-----------------------------------------------------------------

MAIN-ROUTION.                                                   

     EVALUATE TRUE                                               

         WHEN BTS-PASS-TOBIT                                     

              PERFORM BYTES-TO-BIT                               

                 THRU BYTES-TO-BIT-EXIT                          

         WHEN BTS-PASS-TOBYTES                                   

              PERFORM BIT-TO-BYTES                               

                 THRU BIT-TO-BYTES-EXIT                          

         WHEN OTHER                                              

              PERFORM INVALID-REQUEST                            

                 THRU INVALID-REQUEST-EXIT                       

     END-EVALUATE                                                

     .                                                           

MAIN-ROUTION-EXIT.                                              

     GOBACK.                                                     

*-----------------------------------------------------------------

* CONVERT BIT TO BYTES                                           

*-----------------------------------------------------------------

BIT-TO-BYTES.                                                   

     MOVE 0                 TO WK-HWORD-BINARY                   

     MOVE 1                 TO WK-IX                             

     MOVE 128               TO WK-FACTOR                         

     MOVE BTS-PASS-BIT      TO WK-HWORD-02                       

     PERFORM 8 TIMES                                             

        IF WK-HWORD-BINARY = WK-FACTOR                           

        OR WK-HWORD-BINARY > WK-FACTOR THEN                      

           MOVE '1'         TO BTS-PASS-BYTES(WK-IX:1)           

           COMPUTE WK-HWORD-BINARY = WK-HWORD-BINARY             

                                   - WK-FACTOR                   

        ELSE                                                     

           MOVE '0'         TO BTS-PASS-BYTES(WK-IX:1)           

        END-IF                                                   

        COMPUTE WK-FACTOR = WK-FACTOR / 2                        

        COMPUTE WK-IX     = WK-IX + 1                            

     END-PERFORM                                                 

     .                                                           

BIT-TO-BYTES-EXIT.                                              

     EXIT.                                                       

*-----------------------------------------------------------------

* CONVERT BYTES TO BIT                                           

*-----------------------------------------------------------------

BYTES-TO-BIT.                                                  

     MOVE 0                 TO WK-HWORD-BINARY                  

     MOVE 1                 TO WK-IX                            

     MOVE 128               TO WK-FACTOR                        

     PERFORM 8 TIMES                                            

         IF  BTS-PASS-BYTES(WK-IX:1) = '1'                      

             COMPUTE WK-HWORD-BINARY = WK-HWORD-BINARY          

                                     + WK-FACTOR                

         ELSE                                                   

             IF  BTS-PASS-BYTES(WK-IX:1) NOT = '0'              

                DISPLAY '8-BYTE STRING MUST BE ZEROES OR ONES...'

                ADD 8       TO WK-IX                            

                ADD 8       TO BTS-PASS-RESULT                  

             END-IF                                             

         END-IF                                                 

         COMPUTE WK-FACTOR  = WK-FACTOR / 2                      

         COMPUTE WK-IX      = WK-IX + 1                          

     END-PERFORM                                                 

     MOVE WK-HWORD-02       TO BTS-PASS-BIT                      

     .                                                           

BYTES-TO-BIT-EXIT.                                              

     EXIT.                                                       

*-----------------------------------------------------------------

* HANDLE INVALID REQUEST                                         

*-----------------------------------------------------------------

INVALID-REQUEST.                                                

     DISPLAY 'INVALID REQUEST ' BTS-PASS-REQUEST                 

     MOVE 9                 TO BTS-PASS-RESULT                   

     .                                                           

INVALID-REQUEST-EXIT.                                           

     EXIT.                                                       

*-----------------------------------------------------------------

END PROGRAM BITTOOL.

 

BITTEST:

IDENTIFICATION  DIVISION.                                       
PROGRAM-ID.     BITTEST.                                        
******************************************************************
*                     BIT CONVERSION TEST                        
*                       BY ICESCUT                                  
******************************************************************
ENVIRONMENT     DIVISION.                                       
DATA            DIVISION.                                       
WORKING-STORAGE SECTION.                                        
*<<  LINK AREA    >>*                                            
COPY CPBIT.                                                     
77  WK-PGM-BITTOOL         PIC X(8)       VALUE 'BITTOOL '.     
01  WK-AREA.                                                    
     05  WK-HEX.                                                 
*        BINARY NUMBER '01010101'                                
         10  WK-HEX-55      PIC X(1)       VALUE X'55'.          
*        BINARY NUMBER '11010101'                                

         10  WK-HEX-D5      PIC X(1)       VALUE X'D5'.          

*        BINARY NUMBER '11110010'                                

         10  WK-HEX-F2      PIC X(1)       VALUE X'F2'.          

     05  WK-CHAR.                                                

         10  WK-CHAR-1      PIC X(1)       VALUE '1'.            

         10  WK-CHAR-0      PIC X(1)       VALUE '0'.            

PROCEDURE       DIVISION.                                       

*-----------------------------------------------------------------

* MAIN ROUTINE                                                   

*-----------------------------------------------------------------

MAIN-ROUTINE.                                                   

     PERFORM TEST-01                                             

        THRU TEST-01-EXIT                                        

     PERFORM TEST-02                                             

        THRU TEST-02-EXIT                                        

     .                                                           

MAIN-ROUTINE-EXIT.                                              

     STOP RUN.                                                   

*-----------------------------------------------------------------

* TEST1 BINARY NUMBER '01010101' TO '11010101'                   

*-----------------------------------------------------------------

TEST-01.                                                        

     MOVE WK-HEX-55                 TO BTS-PASS-BIT              

     SET  BTS-PASS-TOBYTES          TO TRUE                      

     CALL WK-PGM-BITTOOL USING BTS-PASS-AREA                     

     MOVE WK-CHAR-1                 TO BTS-PASS-BYTES(1:1)       

     SET  BTS-PASS-TOBIT            TO TRUE                      

     CALL WK-PGM-BITTOOL USING BTS-PASS-AREA                     

     IF BTS-PASS-BIT = WK-HEX-D5 THEN                            

        DISPLAY 'SUCCESS'                                        

     ELSE                                                        

        DISPLAY 'FAILURE'                                        

     END-IF                                                      

     .                                                           

TEST-01-EXIT.                                                   

     EXIT.                                                       

*-----------------------------------------------------------------

* TEST2 BINARY NUMBER '11110010' TO '11100010'                   

*-----------------------------------------------------------------

TEST-02.                                                        

     MOVE WK-HEX-F2                 TO BTS-PASS-BIT              

     SET  BTS-PASS-TOBYTES          TO TRUE                      

     CALL WK-PGM-BITTOOL USING BTS-PASS-AREA                     

     MOVE WK-CHAR-0                 TO BTS-PASS-BYTES(4:1)       

     SET  BTS-PASS-TOBIT            TO TRUE                      

     CALL WK-PGM-BITTOOL USING BTS-PASS-AREA                     

*    '11100010' -> X'E2' -> S                                    

     DISPLAY BTS-PASS-BIT                                        

     .                                                           

TEST-02-EXIT.                                                   

     EXIT.                                                       

*-----------------------------------------------------------------

END PROGRAM BITTEST.

 

对BITTOOL使用的步骤(以TEST-02为例):

   1.首先SET BTS-PASS-TOBYTES为TRUE,CALL BITTOOL把WK-HEX-F2转换成8个BYTE的BTS-PASS-BYTES。

   2.然后对BTS-PASS-BYTES进行操作(第四位置0)。

   3.接着SET BTS-PASS-TOBIT为TRUE,CALL BITTOOL把BTS-PASS-BYTES转换为一个BYTE的BTS-PASS-BIT,

   也就是我们想要的结果。                                        

 

三、其实后来想过,用COMP-5 REDEFINES之后,用加减操作来对位进行操作也是一种办法。

posted @ 2010-06-19 08:53  小冰  阅读(1958)  评论(0编辑  收藏  举报