3

$ WORKからCOBOLプログラムで作業しているときに、奇妙なステートメントに遭遇しました。

(DB2から)カーソルを開いている段落があり、EOT(擬似コード)に到達するまでカーソルをループしています。

... working storage ...
01  I                       PIC S9(9) COMP VALUE ZEROS.
01  WS-SUB                  PIC S9(4) COMP VALUE 0.

... code area ...
PARA-ONE.                                                
    PERFORM OPEN-CURSOR
    PERFORM FETCH-CURSOR

    PERFORM VARYING I FROM 1 BY 1 UNTIL SQLCODE = DB2EOT                        
        do stuff here...
    END-PERFORM                                           

    COMPUTE WS-SUB = I + 0                            
    PERFORM CLOSE-CURSOR

    ... do another loop using WS-SUB ...

なぜそのCOMPUTE WS-SUB = I + 0線があるのだろうか。私の理解では、その上に実行ブロックがあるため、I少なくとも常にそうなります1(つまり、最初にEOTがあったとしても、Iその最初の反復で1に設定されます)。

そのCOMPUTE行も必要ですか?私が気付いていない暗黙のキャストを行っていますか?なぜそこにあるのでしょうか?どうしてあなただけじゃないのMOVE I TO WS-SUB

4

3 に答える 3

7

それを愚かと呼びますが、いくつかのコンパイラ(正しいオプションが有効になっている)では、

 01  SIGNED-NUMBER   PIC S99 COMP-5 VALUE -1.
 01  UNSIGNED-NUMBER PIC  99 COMP-5.
      ... 
      MOVE SIGNED-NUMBER TO UNSIGNED-NUMBER
      DISPLAY UNSIGNED-NUMBER

結果:255。しかし..。

COMPUTE UNSIGNED-NUMBER = SIGNED-NUMBER + ZERO

結果:1(署名なし)

したがって、あなたの質問に答えるために、これは、符号付き数値を符号なし数値にキャストするために使用される手法として分類できます。ただし、指定したコード例では、まったく意味がありません。

于 2011-12-14T23:53:58.113 に答える
0

ソースのテストバージョンがこれまでにあったかどうか疑問に思います

COMPUTE WS-SUB = I + 0
    ON SIZE ERROR
        DISPLAY "WS-SUB overflow"
        STOP RUN
END-COMPUTE

開発者が満足してクリーンアップしたときに範囲テストを破棄しましたか?MOVEは、宣言型のSIZEステートメントを許可しません。それは私が見ることができるのと同じくらい多くの理由です。または、すべてのステップで防御コードの必要性を疑問視する微妙なリマインダーとして、COMPUTEを使用して移動する開発者の習慣はありますか?そして、ジョーが指摘したように、おそらく知らないのですが、SIZE句は+ 0がなくても同じように効果的でしょうか?または、メンテナが1つのエラーでオフに苦労し、テスト後に1から0への修正変更がありましたか?

于 2013-01-22T05:57:00.720 に答える
0

「I」の定義は (おそらく) あるプログラマーによってコーディングされ、WS-SUB の定義は別のプログラマーによってコーディングされたことに注意してください (命名は異なり、VALUE 句は同じ目的で異なります)。

プログラマー 2 は「古い学校」のように見えます: PIC S9(4)、半語に「収まる」すべての数字を署名して使用します。S9(9) は、可能な値の範囲に関してはおそらく「はるかに上」ですが、そのようなことは Programmer 1 にはまったく関係ありません。

おそらくプログラマー 2 は、S9(9) COMP を 9999 個よりも少ない (おそらく多くの) 必要な「もの」に使用することに懸念を抱いていたのでしょう。「既存のコードを変更せずに「効率的」になります」。フィールドが符号なしとして定義されたことはありそうにないように思えます。

9 桁の COMP/COMP-4 を計算に使用すると、パフォーマンスが低下します。「ADD 1」を 9(9) と 9(8) と 9(10) に試して、生成されたコードを比較します。9 桁を使用できる場合は 9(10) で定義し、それ以外の場合はフルワードが必要な場合は 9(8) で定義します。

プログラマー 2 は、このことをある程度知っています。

+ 0 の COMPUTE はおそらく意図的なものです。なぜプログラマー 2 はそのように COMPUTE を使用したのですか (元の質問)。

今、それは複雑になるでしょう。

メインフレームには、「バイナリ」フィールドの 2 つの「タイプ」があります。PICture 句によって制限された値を含むもの (USAGE BINARY、COMP、および COMP-4)。フィールドサイズによって制限された値を含むもの (USAGE COMP-5)。

BINARY/COMP/COMP-4 では、フィールドのサイズは PICture から決定され、保持できる値も決定されます。PIC 9(4) はハーフワードで、最大値は 9999 です。PIC S9(4) は、値が -9999 ~ +9999 のハーフワードです。

COMP-5 (ネイティブ バイナリ) では、PICture はフィールドのサイズを決定するだけで、フィールドのすべてのビットがフィールドの値に関連しています。PIC 9(1) から 9(4) はハーフワードを定義し、PIC 9(5) から 9(9) はフルワードを定義し、PIC 9(10) から 9(18) はダブルワードを定義します。PIC 9(1) は最大 65535、S9(1) -32,768 ~ +32,767 を保持できます。

すべて順調です。次に、コンパイラ オプション TRUNC があります。これには 3 つのオプションがあります。STD、デフォルト、BIN および OPT。

BIN は、最も広範囲に影響を与えると見なすことができます。BIN は、BINARY/COMP/COMP-4 を COMP-5 のように動作させます。すべてが実質的に COMP-5 になります。バイナリ フィールドの PICtures は、フィールドのサイズを決定する場合を除いて無視されます (そして、不思議なことに、PICture による最大値を超えると「エラー」になる ON SIZE ERROR を使用します)。IBM Enterprise Cobol のネイティブ バイナリは、排他的ではありませんが、主に「最も遅い」コードを生成します。切り捨ては、フィールド サイズ (ハーフワード、フルワード、ダブルワード) までです。

デフォルトの STD は「標準」の切り捨てです。これは「PICture」に切り捨てられます。したがって、これは「10 進数」の切り捨てです。

OPTは「パフォーマンス」です。OPT を使用すると、コンパイラは、特定の「コード シーケンス」に対して最も「パフォーマンスが高い」方法で切り捨てます。これは、PICture の「範囲外」である「ビット セット」が中間値と最終値にある可能性があることを意味します。ただし、ソースとして使用される場合、「過剰な」ビットが設定されていても、バイナリ フィールドは常に PICture によって指定された値のみを反映します。

OPT を使用する場合、すべてのバイナリ フィールドが「PICture に準拠」していることが重要です。つまり、PICture 定義の外に設定されたビットにコードが依存してはならないということです。

注: OPT が使用されていても、OPTimizer (OPT(STD) または OPT(FULL)) はさらに最適化を提供できます。

これはすべて順調です。

ただし、TRUNC オプションを「混合」した場合、または CALLing プログラムのバイナリ定義が CALLed プログラムと同じでない場合、「pickle」がすぐに発生する可能性があります。「混在」は、同じ実行単位内のモジュールが異なる TRUNC オプションでコンパイルされた場合、またはファイルのバイナリ フィールドが 1 つの TRUNC オプションで書き込まれ、後で別のオプションで読み取られた場合に発生する可能性があります。

さて、プログラマー 2 は次のようなことに遭遇したのではないかと思います: TRUNC(OPT) を使用して、フィールド内の「余分なビット」に気づき、それらを処理する必要があると考えたか、または実行中にオプションの「混合」を介して-ユニットまたは「ファイルの使用全体」で、彼らは「余分なビット」に気付き、それについて何かをする必要があります(「ミックスを削除する」必要がありました)。

プログラマー 2 は、COMPUTE A = B + 0 を開発して、特定の問題 (認識または実際の問題) に「対処」し、それを一般的な作業に適用しました。

これは「推測」、またはより適切には、既知の情報で機能する「合理化」です。

これは「偽の」修正です。問題がなかった (TRUNC(OPT) が機能する通常の方法) か、正しい解決策は、モジュール/ファイルの使用全体で TRUNC オプションの「正規化」でした。

多くの人が急いでコードに COMPUTE A = B + 0 を入れてほしくありません。まず、彼らはなぜそれをしているのかわかりません。継続については、それは間違ったことです。

もちろん、見つけたものから「+ 0」を削除しないでください。TRUNC が「混在」している場合、プログラム「動作」を停止する可能性があります。

BINARY/COMP/COMP-4 に「ADD ZERO」を使用した状況が 1 つあります。これは「ミッキーマウス」プログラムで、何かを試すためだけのプログラムです。ここでは、オプティマイザーを「だます」方法として使用しました。そうしないと、オプティマイザーは変更されない値を認識し、コンパイル時にすべての値が既知であるため、リテラル結果を使用するコードを生成する可能性があります。(私が PhilinOxford から取り上げた、これを行うためのおそらく「よりきちんとした」より柔軟な方法は、フィールドに ACCEPT を使用することです)。これは、問題のコードには当てはまりません。

于 2013-01-21T01:56:19.917 に答える