1

数値変数への英数字の移動により、予期しない結果が発生しました。コードfyrは次のとおりです。

  DATA DIVISION.                                 
  WORKING-STORAGE SECTION.                       
  01  WS-VAR-STR       PIC X(3) VALUE SPACES.                
  01  WS-VAR-NUM       PIC 9(3) VALUE ZEROES. 
  PROCEDURE DIVISION.                            
      MOVE '1'         TO WS-VAR-STR                  
      MOVE WS-VAR-STR  TO WS-VAR-NUM
      DISPLAY 'STRING > ' WS-VAR-STR '< MOVED > ' WS-VAR-NUM '<'

      IF WS-VAR-NUM >= 40 AND <= 59
         DISPLAY 'INSIDE IF >' WS-VAR-NUM
      ELSE 
         DISPLAY 'INSIDE ELSE >' WS-VAR-NUM
      END-IF
      GOBACK                                     
      .  

    OUTPUT:
    STRING > 1  < MOVED > 1 0<
    INSIDE ELSE >1 O

結果は奇妙で、「1」が「1 0」として数値変数に移動される理由を理解したいと思います。興味深いことに、条件付けにも問題はありませんでした。あなたの意見を共有してください。ご関心をお寄せいただきありがとうございます。

4

1 に答える 1

3

Basically you have done an illegal MOVE. Moving alphanumeric to numeric fields is valid provided that the content of the alphanumeric field contains only numeric characters. This reference summarizes valid/invalid moves.

What were you expecting as a result?

Moves of alphanumeric fields into numeric ones are done without 'conversion'. Basically you just dropped a one digit followed by two spaces into a numeric field. the '1' was ok, the two spaces were not. The last two bytes of WS-VAR-NUM contain spaces.

But wait... why is the last character a zero? The answer to this is a bit more complicated. Items declared as PIC 9 something are represented in Zoned Decimal. Each digit of a zoned decimal number is represented by a single byte. The 4 high-order bits of each byte are zone bits; the 4 high-order bits of the low-order byte represent the sign of the item. The 4 low-order bits of each byte contain the value of the digit. The key here is where the sign is stored. It is in the high order bits of the last byte. Your declaration did not include a sign so the MOVE statement blows away the sign bits and replaces them with default numeric high order bits (remember the only valid characters to MOVE are digits - so this patch process should always yield a valid result). The high order bits of an unsigned zoned decimal digit are always HEX F. What are the low order bits of the last byte? A space has an ebcdic HEX value of 40. A zero is HEX F0. Since the MOVE statement "fixes" the sign automatically, you end up with HEX F0 in the low order digit, which happens to be, you guessed it, zero. None of the other 'digits' contain sign bits so they are left as they were.

Finally, a DISPLAY statement converts zoned decimal fields into their equivalent character representation for presentation: Net result is: '1 0'.

BTW The above discussion is how it works out on an IBM z/OS platform - other character sets (eg. ASCII) and/or other platforms may yield different results, not because IBM is doing the wrong thing, but because the program is doing an illegal MOVE and the results are essentially undefined.

于 2011-05-26T20:20:49.313 に答える