外出自粛中でも楽しく過ごす!QAまとめ>>

C言語にてゾーン10進数→パック進数、パック10進数→ゾーン10進数にする
簡単な方法ありませんか?

A 回答 (4件)

どのレベルの質問かわかりませんが、4bit単位のアクセスが出来ると簡単に移行できるので、



union zone_t{
char a;
struct hb_t {
char l:4;
char h:4;
} hb;
} a[100]; /* this is for zone */
struct pack_t {
char b:4;
} b[50]; /* this is for pack */

みたいに4bit単位に操作できるように宣言してあげると、関数の中ではbit操作しなくてもいいから楽に処理できます。

一例として、zone -> pack
i = 0;
while (a[i].hb.h == 0x3) {
b[i].b = a[i].hb.l;
i++;
};
b[i].b = a[i].hb.h;

でしょうか。
ちゃんと動作は確認していないので、ちょっと自信ないですが。
    • good
    • 0

下のものですが、もしかしたら、


struct pack_t {
char b:4;
} b[50]; /* this is for pack */
だと、50byte使ってしまったような、、、
(仕様を忘れてしまいました。)
この場合は、やはりzoneと同じようにh,lみたいに2つ定義する必要があります。

では。
    • good
    • 0

こんにちは。



C言語では、Pack/Unpackに対応した進数変換関数はありません。
ゾーンの場合であれば、EBCDICコードかJISコード化によって変わってきます。
ただ、ゾーンもパックも後ろのバイトに符号(+/-)がつきますので
規則性はありますので、自作するしかないのでは。

以下、私が作るとしたらと仮定して
1.必要なものをクラス化する。(Cであれば適せん修正)
  元の値の変数、ゾーン値変数、パック値変数、等の変数
  Base2Zone(...)関数、Base2Pack(...)、
  Zone2Pack(...)関数、Pack2Zone(...)、等の関数

関数の中は、ビット演算のあらしになりますが、それほど難しいものでは
ないと思います。
尚、大きな値を使用するようであればバイト数にも注意してください。
    • good
    • 0

C言語には自信があるのですが、ゾーンとパックって何ですか?って感じで回答出来ないので補足して欲しいな。

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q数字文字列をパック10進数に変換するにはどうしたらいいのでしょうか?

"1234567"という文字列を
パック10進数に変換したいのですが、
どのようにしたら良いのでしょうか?

まず左に4bitシフトさせてから符号部分の4bitを
うまく取り除ければ出来ると思うのですが、どう実装したら良いか分かりません。

よろしくお願いします。

Aベストアンサー

#2です。入力文字のサイズと変換結果を格納するサイズを指定して、変換を行いたいように見えましたので、そのように修正しました。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void topack(int len1,char *str1,int len2,char *str2)
{
//len1:入力文字列長
//str1:入力文字
//len2:出力結果長
//str2:出力結果
int s1 = 0;
int i;
char x;
memset(str2,0x00,len2);
for (i=0;i<len2;i++){
s1++;
if (s1 >len1) break;
x = *str1++ & 0x0f;
x = x << 4;
s1++;
if (s1<=len1){
x |= *str1++ &0x0f;
}
*str2++ = x;
}
}
int main()
{
unsigned char out[8];
memset(out,0xff,sizeof(out));
topack(7,"12345679875",4,out);
printf ("out=%02x%02x%02x%02x%02x%02x%02x%02x\n",
out[0],out[1],out[2],out[3],out[4],out[5],out[6],out[7]);
memset(out,0xff,sizeof(out));
topack(8,"12345678777",3,out);
printf ("out=%02x%02x%02x%02x%02x%02x%02x%02x\n",
out[0],out[1],out[2],out[3],out[4],out[5],out[6],out[7]);
topack(3,"12345678777",4,out);
printf ("out=%02x%02x%02x%02x%02x%02x%02x%02x\n",
out[0],out[1],out[2],out[3],out[4],out[5],out[6],out[7]);
return 0;
}

#2です。入力文字のサイズと変換結果を格納するサイズを指定して、変換を行いたいように見えましたので、そのように修正しました。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void topack(int len1,char *str1,int len2,char *str2)
{
//len1:入力文字列長
//str1:入力文字
//len2:出力結果長
//str2:出力結果
int s1 = 0;
int i;
char x;
memset(str2,0x00,len2);
for (i=0;i<len2;i++){
s1++;
if (s1 >len1) break;
x = *str1++ & 0x0f;
x = x << 4;
...続きを読む

QCOBOL数値転記の仕様

このたび、まったくの未経験のCOBOLをやることになりました。
で、数値データの表し方になんやかやとやたら方法があるようなのですが、それらを互いに「転記」したときに、どういう結果になるものか、皆目わからないんです(環境はCOBOL85でWindows上での開発です)。
テクニックとしては基本だと思うのですが、それでいてどこにも説明されていな~い!フリーのCOBOLツールは見つけてきましたが、使い方が???なもので…。
 たとえば、

 01 X1 PIC XX (数値が入ってるとします)
 01 N1 PIC 99
 01 D1 PIC 99 COMP
 01 B1 PIC 1(16) BIT

な場合、X1とN1は直接
 MOVE N1 TO X1
などとやってもデータは失われないと思うんですが、他の形式での操作は(桁あふれとか無視して)ちゃんと転記できるのでしょうか。

いま特に、D1からX1へというパターンが多いです。1バイトの2進データを、数値の文字列として使おう、というんです。いわば、1バイトを3バイトに展開してやるんです。何も考えずに書けば、
 01 D2 PIC 9(4) COMP VALUE 97
 01 X2 PIC X(3)
 MOVE D2 TO X2
でしょうけど、たぶん'a△△'になるだけのような気がします…。
 それとも、
 01 N2 PIC 9(4)
 MOVE D2 TO N2
 MOVE N2 TO X2
などとやっていけたりするのでしょうか。

いったいどうなるのでしょう、いろいろ書いちゃいましたけど、各々の転記の仕組みを教えてください。

また、COBOLの(お堅い規格を書き写しただけでない)解説のサイトなどあれば、ご紹介いただけますでしょうか。

このたび、まったくの未経験のCOBOLをやることになりました。
で、数値データの表し方になんやかやとやたら方法があるようなのですが、それらを互いに「転記」したときに、どういう結果になるものか、皆目わからないんです(環境はCOBOL85でWindows上での開発です)。
テクニックとしては基本だと思うのですが、それでいてどこにも説明されていな~い!フリーのCOBOLツールは見つけてきましたが、使い方が???なもので…。
 たとえば、

 01 X1 PIC XX (数値が入ってるとしま...続きを読む

Aベストアンサー

ShiozawanoYukiさんはCOBOL未経験とのことですが
ご質問のような数値と文字との間の転記はCOBOL上規約はありますが実際には例外的にしか行われないでしょう。

COBOLコードの厳しい社内ルールを定めてる会社では数値と文字との間の転記は禁止されています。
(桁あふれ、計算時に不能や範囲外の値になったり、ひどいとエラー終了になるか引き起こしたりするからです。)
転記する場合は同じ桁数同士のみで行う社内ルールを決めているところもあります。
(桁あるれ対策です。)

*数値と文字との間の転記はデータの定義で対処します。

COBOLのデータは構造体になっています。
(ご質問のようなデータ構造はフラグ、繰り返しや一時的な変数などには使用しますが普通はレベルを使用したデータ構造で定義します。)

>MOVE N1 TO X1
のコードのデータは

 01 X.
  02 X1 PIC 99.
 01 N1 PIC 99.

などと定義し転記後に文字で使用する場合は”X”(2桁)を使用します。
しかし、ただ”N1”を文字として使用するだけである場合は

 01 NX.
  02 N1 PIC 99.

と定義し、”NX”(2桁)を文字として使用する方法もあります。
(これは9タイプとXタイプの内容が同じため利用できますがバイナリなどでは転記してから利用します。)


逆に数値から文字に転記する場合は

 01 D2 PIC 9(4) COMP VALUE 97.
 01 X2.
  02 X9 PIC 9(4).
 01 XR REDEFINES X2.
  02 XR1 PIC X(02).
  02 XR2 PIC X(02).

   MOVE D2 TO X9.

となり文字として使用する場合は”X2”(4桁)を使用します。
”X2”は数字から転記されたので”0097”が入っています。

”X2”を”△△97”にする場合は”X9”を”ZZZ9”または”ZZZZ”(”Z(04)”)の編集項目で定義すれば実現できます。
(”0”(”0000”)を転記した場合に”ZZZ9”は”△△△0”、”ZZZZ”は”△△△△”になります。)

4桁を上2桁と下2桁で使用する場合は上記のように”X2”を再定義(REDEFINES)し”XR1”、”XR2”を使用します。
(個人的には最上位レベルでの再定義は避けるようにしています。)

*実は転記を悩まずに行うには、実は上の厳しい社内ルールと記した”同じ項目種類、桁数でのみ転記”を行い、項目種類の変換はデータ定義で行うのがポイントです。


*COBOLを理解するためにはデータ構造を理解することが良いと思います。
 (命令は他の言語より少なく対応が容易です。ただ、少ない分、自分でコード作成が必要です。ここが他の言語しか知らないプログラマには大変かもしれません。)

後、ピリオドを付けないとのルールがないなら、命令の最後にはピリオドを付けましょう。
(IF文の中では逆に付けません。そのため逆にピリオドがトラブルの原因ともなり、モジュールの最後だけに付けるとの社内ルールを決めているところもあります。)

>また、COBOLの(お堅い規格を書き写しただけでない)解説のサイトなどあれば、ご紹介いただけますでしょうか。

残念ですがCOBOLは他の言語と違い歴史がある割りには定番類があまりありません。

最新のCOBOLは他の言語のように色々な命令が追加されているようですが、本来は当時のプログラミングの専門家以外でもプログラムを作成することを目標に設計されています。
(当時といっても、もう半世紀も前の話ですが・・・)
そのため、元は限られた命令と定義されたデータ構造だけでプログラムが作成できます。
(バッチであればファイル処理と帳票処理を中心に憶えれば良いと思います。問題はオンラインとWebの場合ですが真似からなれるしかないかもしれません。)


参考になるでしょうか?

ShiozawanoYukiさんはCOBOL未経験とのことですが
ご質問のような数値と文字との間の転記はCOBOL上規約はありますが実際には例外的にしか行われないでしょう。

COBOLコードの厳しい社内ルールを定めてる会社では数値と文字との間の転記は禁止されています。
(桁あふれ、計算時に不能や範囲外の値になったり、ひどいとエラー終了になるか引き起こしたりするからです。)
転記する場合は同じ桁数同士のみで行う社内ルールを決めているところもあります。
(桁あるれ対策です。)

*数値と...続きを読む

QCOBOLのCOMP形式について

久しぶりにCOBOL開発をする事になり、
懐かしく思ってPGを解析しているとどうしても
思い出せないものがありました。 
COMP形式です。
AAA PIC 9(05)
     5バイトで12345ならば「F1F2F3F4F5」
BBB PIC 9(05)COMP-3
     3バイトで12345ならば「12345F」
CCC PIC 9(05)COMP
     この場合は何バイトになるのでしょうか?
     及び、12345の場合、どのようになるのでしょうか?

以上、初歩的な部分ですが皆様よりご教授頂きたいと思います。
よろしくお願いします。

Aベストアンサー

メーカーやOSによって違うのではないでしょうか?

メインフレームの日立であれば、
PIC S9(n) COMP
の場合、n=1~4は2バイト、n=5~9は以上は4バイト、10~18は8バイトの2進数になります。

Qゾーン10進数とパック10進数の違い

今度、内定者向けの研修で基本情報の対策をするのですが、その際に「ゾーン10進数」と「パック10進数」の違いを説明する事になりました。

だいたいの違いは分かるのですが、これをコンピュータの知識のあまりない学生に分かりやすく説明するにはどうすれば良いでしょうか?

皆様のお知恵をお借りしたいと思います。よろしくお願い致します。

Aベストアンサー

ゾーン10進数もパック10進数も、基本的には数字を文字として扱った
データの形です。

で、単純に数字を「文字」として扱う場合10種類のコード、即ち4ビット
あれば表現出来るのですが、AscII文字列は8ビットもデータを使う=
数値表現にはなくてもいいビットが4ビットもあるんです。

パック10進数は、この「もったいない4ビット」を消して、4ビットで
数字を表わしたものです。ただ、4ビットだけだと「符号」が分からなく
なるので、最後に符号の「4ビット」をつけます。

文字扱いの数字を4ビット×2に「パッキング(詰め込んだ)」数字形式
なので、「パック」と言うんですね。

ちなみにゾーン10進数は、数字を数字たらしめるゾーン=前半4ビット
(実際にゾーン部って言います)があるのでゾーン10進数と言います。

・・・コレで説明は大丈夫ですかね?

参考URL:http://www.jtw.zaq.ne.jp/kayakaya/new/kihon/text/zonepack.htm

QLinuxの「セクタ」と「データブロック」の違い

Linuxの本を読んでいたら、
データを保存する領域として「セクタ」と「データブロック」という
二つの単語が出て来ました。

本を読む限り、微妙に意味合いが違っているようなのですが
どのように違うのか明確に分かりませんでした。

どなたか分かる方教えて下さい。

Aベストアンサー

セクタはハードウェア的な最小単位というのは正しいですが、これもHDDでは標準で512バイトというだけで実際には可変です。

※物理フォーマット時に設定(変更)する事ができます。


ブロックサイズは入出力時に一度に扱う単位で管理単位とは違います。

例えばe2fsの場合、mke2fsコマンドで調整できる値としてフラグメントサイズとブロックサイズがあって管理の最小単位はフラグメントサイズで入出力の最小単位はブロックサイズとなります。

例えばフラグメントサイズが1024バイトでブロックサイズが4096バイトの場合に4100バイトのファイルと3000バイトのファイルを書き込む時、4100バイトのファイルは4096+4なので4096バイトのブロックと1024バイトのフラグメント1つ、3000バイトのファイルは2048+952なので1024バイトのフラグメント3つとして扱われ、4つまでのフラグメントは1ブロックとして一度の入出力で読み書きされる場合があります。

※入出力はブロックサイズで行われますが、管理はフラグメントサイズで行われるので速度は4096ブロックの速度で、利用効率は1024バイト/ブロック時の利用効率で使えます。(カーネル内で組立て・分解されるのでその処理に若干の負荷は余分に掛りますが)

前の例では単純にブロックサイズで管理した場合、4100バイトのファイルが2ブロックを消費し、3000バイトのファイルが1ブロックを消費するので合計3ブロックを占めますが、ブロックとフラグメントの2層で管理する事により、1ブロック+1/4ブロックと3/4ブロックで合計2ブロックに占有ブロックを減らせる事になります。効率のみでなく速度も入出力の回数が減らせて向上します。


http://ja.wikipedia.org/wiki/Unix_File_System

上記ページで『ファイルの最後の部分はブロックサイズ未満になるので、それをブロックを分割したサブブロックに格納することで領域を有効活用できるようにする。これをブロックのサブアロケーション、テールマージ、テールパッキングなどとも呼ぶ』と説明されています。また、『Linux の ext2 ファイルシステムは UFS の影響を受けている』とも。

セクタはハードウェア的な最小単位というのは正しいですが、これもHDDでは標準で512バイトというだけで実際には可変です。

※物理フォーマット時に設定(変更)する事ができます。


ブロックサイズは入出力時に一度に扱う単位で管理単位とは違います。

例えばe2fsの場合、mke2fsコマンドで調整できる値としてフラグメントサイズとブロックサイズがあって管理の最小単位はフラグメントサイズで入出力の最小単位はブロックサイズとなります。

例えばフラグメントサイズが1024バイトでブロックサイズが4096バイトの...続きを読む

Q10進数をBCDに変換する方法

10進数から2進化10進数(BCD)に変換するところで疑問があります。
たとえば、10進数の3846をBCDに変換する場合答えはどのようになりますか?

私なりに考えたところまでを示しますが、答えがわかりません。
どこに考え方の間違いがあるのでしょうか?

まず、3846を2進数に変換しました。
3846 → 0000111100000110 (2進数)となります。

ここからBCDに変換する場合、4ビットずつを1つと考えて数字を表現するので、上記の2進数の頭から4つずつ分けて考えると

1つ目 0000
2つ目 1111
3つ目 0000
4つ目 0110
の4つにわけました。

続いて、それぞれを10進化しました。
1つ目 0000 → 0
2つ目 1111 → 15
3つ目 0000 → 0
4つ目 0110 → 6

ここで疑問が出てきます。
2つ目のところで、1111を10進化すると15となってしまい桁上りが生じます。
この場合どのように処理するのが良いのでしょうか?

どなたかご教授ください。

Aベストアンサー

BCDに変換する際、数値全体を2進数に変換する必要はありません。
各桁を構成している数値を2進数に変換して、合体させればよいです。
10進数の3846をBCDに変換するのであれば、
3 → 0011
8 → 1000
4 → 0100
6 → 0110
より、
0011 1000 0100 0110
です。


人気Q&Aランキング