EBCDICコードでの数字
AS/400というマシンの、文字コードはEBCDIC(Extend Binary
Coded Decimal Code)と呼ばれる文字コードです。PCなどでは、シフトJISなどで行われていますが、AS/400は大型機や汎用機と同じく、EBCDICコードでデータを処理しています。さて、ここで数字のお話をしましょう。ハードディスクへの記録形式として、(つまり、ファイルのフィールド定義として)、数字にはいくつかの保管形式が有ります。皆さんが、基本として、知っておかねばならないのは、パックとゾーンです。(Binaryはどうしようかと思いましたが、いきなりbinaryフィールドは使わないと思いますので、割愛します。)
ゾーンとパック
AS/400 RPG/400 使用者の手引き 9.1
ファイル内のフィールドの形式
RPG/400
プログラムの入力フィールドおよび出力フィールドは文字、ゾーン
10 進数、パック 10
進数、あるいは2進数形式とすることができます。先行または後書き符号は、ゾーン
10
進数の場合にだけ指定することができます。数値入力フィールドはすべて、(データ構造中にないかぎり)内部処理のためにコンパイラーによってパック 10
進数に変換されます。数値データがパック 10
進数であっても、ゾーン 10
進数であっても、あるいは2進数形式であっても、プログラムは同じように実行します。しかし,データがパック
10
進数形式になっていると、システムは演算をより効率よく処理します。データ構造内のサブフィールドは、常にサブフィールド仕様で指定した形式に保たれます。
プログラム内部では、ゾーンもパックもすべて、パック数字として処理され、ディスクに書き出すときに、パックからゾーンにしたりして形式変換をしているのですね。そもそも、PACKというのは、「荷物を鞄に詰め込む」ことです。ここでは、数字を短く詰め込んでいるのです。
ゾーン10 進数の場合
これは、ルールであって、覚えるしか有りません。EBCDICでは、数字は必ず、16進数
「F + 0から9」となります。つまり、もし、5250のスクリーン上で、1と入力したら、その1は、16進数では
'F1'と入力されたのと同じです。文字タイプであっても、数字タイプであっても、ここは同じです。AS/400そのものが、X'F1'をキャラクタ表示すると、1となるのです。
「え?じゃあ、ゾーンの数字って、文字と同じなの?」と思われるでしょう。9割当たっています。残り1割は、その数字が、文字フィールドに入るのか、数字フィールドに入るのかで、プログラムでの処理が違うのです。
たとえば、数字フィールドでは、「負数」があります。文字フィールドにマイナス、という考えは有りません。数字のコードや電話番号は、負数なんて無いですよね。でも、たとえば、売りあげの数字では、返品があると、マイナスが出てきます。さらに、数字タイプのフィールドに入っている数字は、四則演算が可能ですよね。ここが大きなポイントです。
ゾーン10 進数数字の負数の表現
ゾーンの数字の負数は、16進数で表現する、数字の右端の上位4ビット(先ほどFと言った部分)が、Dになるのです。図解すると、
16進数 |
F |
F |
F |
F |
F |
1 |
2 |
3 |
4 |
5 |
文字 |
1 |
2 |
3 |
4 |
5 |
この図では、文字で1は16進数では、F1で有ることを意味しています。F1を縦に記述していますね。これを、通常に数字フィールドに入っているとすると、+12345を意味します。
16進数 |
F |
F |
F |
F |
D |
1 |
2 |
3 |
4 |
5 |
文字 |
1 |
2 |
3 |
4 |
N |
今度は、上記の数字を負数にしました。最後のFのみ、Dに変わっていますね。ところで。文字がNになっています。実はこれで正しいのです。EBCDICの文字コード表を見れば分かりますが、16進数'D5'は、アルファベットNです。これじゃ、困るじゃないか、と思われるでしょう。いいのです。数字編集コードをつけると、たとえば、「J」をつけると、12,345-と表示されるのです。もし、編集を忘れると、1234Nと出ます。数字最後の1文字が、こうなっていたら、まず間違いなく数字編集にミスが有ることになります。念のため、上位4ビットがDで始まる文字コードを出しておきましょう。
AS/400 アドバンスト・シリーズ プログラミング要覧 バージョン
3 17.0 第17章 文字コードに出ていますよ。
16進数 |
D |
D |
D |
D |
D |
D |
D |
D |
D |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
文字 |
J |
K |
L |
M |
N |
O |
P |
Q |
R |
パック 10 進数の場合
今度は、数字をパック化して記録してある場合のことです。プログラムの内部でも、また、数字のパラメータを渡す場合もパック化された数字でなければなりません。この数字のパック化とは、早い話、ゾーン10進数の上位4ビットの'F'を有効利用して、占有バイト数を縮めたものです。数値演算のパフォーマンスがよいようです。
これは、数値で 12345+を意味しています。最後の4ビット(F)が符号となります。キャラクタでは、うまく表示できません。
これは、数値で 12345-を意味しています。最後の4ビット(D)がマイナスを意味します。ところでここでは、12345と奇数の桁数をお見せしましたが、もし、これが偶数桁だと、4ビットの無駄が出ます。
このように、符号エリアは必ず、最後の4ビットなのですが、偶数だと、先頭に16進数0がはいり、プログラムでは一切アクセス出来ません。ファイルのレイアウトを考える場合、この無駄を省くように、設計しましょう。具体的に言えば、計算対象となる数字は、必ず数値の奇数桁のパックにする、という感じです。有る程度、ファイルのサイズが小さくなりますね。勿論、文字フィールドに数字(演算やマイナスは出来ないが)を入れても構いません。社員コードや、商品コードなどです。この場合、文字フィールドの中の数字は、正数のゾーン10進数と同じです。(計算は出来ませんよ)。日付なども、どうしても偶数桁になってしまうのですが、これをパックにして、無理矢理奇数桁にすると、後々妙なことがあるので、偶数桁でしたほうが、良いと思います。妙なこととは、日付=6または8桁なのに、7桁とか9桁では、様々な局面で例外扱いになりそうだ、という意味です。(すべて、このようにするという標準化をしても、購入したパッケージは6または8桁のままのはずです。)
漢字の扱いも、パソコンと違うルールが有ります。勿論、今度は数字ではなく、文字フィールドの中の話しです。DDSで、フィールドタイプが、J(漢字専用)、O(混用)などが、漢字のフィールドです。Aとすると、SBCSとなります。ファイルに1つでもDBCS(漢字)フィールドが有れば、そのファイルは漢字の属性を持つファイルになります。
ここから、漢字の制御コードの話しをします。以下、X'0E'やX'0F'は、16進数の0Eと0Fを表し、各々、1バイトの文字です。X'0E'をShiftOut(SO)、X'0F'をShiftIn(SI)ともいいます。
制御コードX'0E'とX'0F'の役割
普通、漢字以外の文字コードは8ビット(1バイト)で表現されます。SBCS(Single Byte Character Set)と呼ばれるのが、1バイトの文字コードです。ワープロで言えば、「半角」の事です。しかし漢字の場合、1文字を2バイトで表現します。これを、DBCS(Double Byte Character Set)と呼びます。まあ、ワープロで言えば、「全角」の事です。
昔は、IBMは、IGC(ideographic;象徴による表意,表意文字使用)という言葉を使っていました。象形文字とでも言っているようで、「失礼な」と思っていましたが、AS/400からはDBCSと言う言葉が、代わりに使われます。つまり、IGC=DBCS=漢字のことです。 たまにパラメータやキーワードでIGCが残っているのを見つけます。DDSのIGCCNVとか、CRTSRCPFでIGCDTAなど。すべて、IGCは漢字のことです。上位互換の保障のために、残さざるを得なかったのでしょう。 |
さて、コンピュータにとって、基本は1バイトの文字(SBCS)です。つまり、こちらが、なにも指示しなければ、1バイトの文字と考えています。ところが、漢字を表したい場合は、2バイトですよね。1バイトづつ処理している人に、今度は2バイトなんだぞ、と漢字を渡す前に、知らせなくてはなりません。これが、SO(X'0E')です。この制御コードを受け取ると、コンピュータは、SOに続いてくるのが、2バイトで1文字のものと判断するのです。そして、SI(X'0F')が来るまで、ずーっと、2バイトで一文字という扱いをするのです。
16進数 |
0 |
4 |
5 |
4 |
F |
0 |
E |
F |
8 |
8 |
2 |
F |
文字 |
SO |
漢 |
字 |
SI |
暗闇のデータのやりとり
こう考えてください。もし、あなたが、「目も見えず」「耳もない」状態で、手探りで、データを判断しているとします。手触りだけで、データを判断しているのです。普通は、1バイト1文字と、予め覚え込まされているので、1バイト単位に1文字として、扱っています(SBCS)。やがて、SO制御コードが来ます。すると、あなたは、「あ、次から2バイトで1文字なんだ(DBCS)」と判断して、1バイト来ても処理をせず、残りの1バイトを待って、2バイト分手元に来てから、1文字として扱います。1バイト来てもなにもしないで、残りの1バイトがきて、やっと、1文字...これをずーと繰り返しはじめます。やがて、今度はSI制御コードが来ます。「ああ、やっと、前の状態にもどるんだ。1バイトで1文字だ」と考えて、1バイトで1文字の状態(SBCS)に戻ります。実際コンピュータは、データのみにすがって、活動しているものです。人間のように5感はないのです。
16進数 |
C |
C |
C |
0 |
4 |
5 |
4 |
F |
4 |
C |
0 |
C |
C |
C |
C |
1 |
2 |
3 |
E |
F |
8 |
8 |
2 |
4 |
A |
F |
6 |
7 |
8 |
9 |
文字 |
A |
B |
C |
SO |
漢 |
字 |
だ |
SI |
F |
G |
H |
I |
|
SBCS ここまで → |
シフト |
← DBCS → |
シフト |
← ここから SBCS に復帰 |
だいたいの感じは掴めましたか?
おわかりになったと思いますが、漢字は、必ず、X'0E'とX'0F'で囲まれます。これは、最低必要な条件で、これがおかしくなると、印刷や表示で、漢字が壊れます。また、漢字は必ず、4バイト以上の偶数桁です。
漢字が壊れる
漢字が壊れるとは、以下の場合です。印刷では、印刷不能文字とか、画面ではキーボードエラーという4桁コードが出てきます。
SOが来て、2バイトで1文字の処理が開始しているのに、SIが何らかの理由で無くなり、本来SBCSのところまで、2バイトで1文字の扱いを続けている場合
16進数 |
C |
C |
C |
0 |
4 |
5 |
4 |
F |
4 |
C |
|
C |
C |
C |
C |
1 |
2 |
3 |
E |
F |
8 |
8 |
2 |
4 |
A |
|
6 |
7 |
8 |
9 |
文字 |
A |
B |
C |
SO |
漢 |
字 |
だ |
? |
? |
? |
|
SBCS ここまで → |
シフト |
← DBCS(のつもり?) → |
漢字DBCSの部分なのに、SOが無いために、2バイト一組で1文字を、1バイトづつ1文字にしてしまっている場合
16進数 |
C |
C |
C |
|
4 |
5 |
4 |
F |
4 |
C |
0 |
C |
C |
C |
C |
1 |
2 |
3 |
|
F |
8 |
8 |
2 |
4 |
A |
F |
6 |
7 |
8 |
9 |
文字 |
A |
B |
C |
? |
? |
? |
? |
? |
? |
? |
SI |
F |
G |
H |
I |
|
SBCS ここまで → |
← SBCS(のつもり?) → |
大抵は、O仕様書などで、終了位置を間違えて記入して、他の文字と重なったりしているのが原因です。画面の場合、ファイルの中のデータが最初から壊れていることもあります。何にせよ、これらの障害を取り除くのが先決です。特に、IBMマシン以外からのデータ移行には、この0E0Fに注意です。
ところで、シングルコーテーションって知っていますよね。2バイト1文字を、1バイトずつ検査するときに、シングルコーテーションX'7D'を見つけると、SEUなどでエラーが起きたりします。単純な様ですが、仕方のないことと思ってください。シングルコーテーションは、文字の固定情報などで、O仕様書で使われます。以下の例のように、固定情報は、必ず、「'」で括られていますよね。このシングルコーテーションが漢字コードに含まれると、おかしくなる場合がある訳です。
O E 2 #HED
O 12 'ファイル名'
O 26 'レコード様式'
O 31 'タイプ'
O 41 'レコード長'
O 48 'アクセスパス'
O 57 '保 守'
O 63 '重複'
O 69 '選択'
O 75 'キー数'
O 86 '基礎ファイル'
このシングルコーテーションを含む漢字コードと、本来のシングルコーテーションと分けて、漢字コードと示すためのオプションが実は、H仕様書に有ります。
57桁目に1をセットすると、リテラルの中のDBCSを検査します。通常は、これを1と指定したほうが良いでしょう。
尚、シングルコーテーションは、X'7D'です。これを含む漢字を、如何に示します。たとえば、美はX'457D'、士は、X'467D'...と読みます。
漢字 |
16進数 |
美 |
45 |
7D |
士 |
46 |
7D |
角 |
47 |
7D |
値 |
48 |
7D |
炉 |
49 |
7D |
巾 |
4A |
7D |
閉 |
4B |
7D |
鹸 |
4C |
7D |
謡 |
4D |
7D |
巴 |
4E |
7D |
涌 |
4F |
7D |
欺 |
50 |
7D |
瞭 |
51 |
7D |
緋 |
52 |
7D |
噛 |
53 |
7D |
捌 |
54 |
7D |
碩 |
55 |
7D |
次回は、C仕様書の前に、サイクル処理を先に説明します。O仕様書にも関連しますよ。
起立、礼、着席
1998/8/29 |