DimやGetの書き方

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
メッセージ
作成者
斉藤圭佑
記事: 5
登録日時: 2006年10月31日(火) 19:40
お住まい: 神奈川

DimやGetの書き方

#1 投稿記事 by 斉藤圭佑 »

MS-DOS上で動くBASICをWindows上で動かせるように編集しています。
プログラムの内容の概要は「バイナリデータをテキストデータに変換する」
です。編集を行ってる際に

・Get #1,○,○ の○の中に何を記述すればよいか
 1090 1790 2390 2990行目

・Dim () As Double のカッコ内に文字を使いたいがどうしたらいいか
 1710 2320 2930行目

の2項目でつまづいてしまいました。
また、エラー表示にはなっていませんが、

Field #1,128 As X$ 1070行目
Field #1,128 As Y$ 1071行目

と同じ#1を2行に分けて表現しているのですが大丈夫でしょうか。
BASIC自体も初心者で非常に初歩的な質問であるとは思いますが
よろしくお願いします。
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

#2 投稿記事 by konisi »

ぱっと見なので完全な答えにはなりませんがご了承。

まず、187::2320行目
DTBAAは31::1212行目でLong型として定義されてますが、これがそもそもの間違いです。
Dimのカッコ内に英文字を書くことは出来ますが、その文字が使われるより以前にConstで定義しておく必要があります。
この場合はファイルから読み取って判断しているようなので、旧N88BASICに出てくるような関数だけでは書き換えきれないと思います。
後でプログラムの意味を汲み取ってそこらへんを解決しようかと考えています。
それと、取り敢えず色々なことを踏まえて2ブロック書き換えてみます。
Dim等は省略するので後で書き足して置いてください。

コード: 全て選択

'PNT=400'取り敢えず放っておきます。
Open "DAT3-14.FRK" As #1
Field #1,1
Get #1,1,X$
Get #1,1,Y$
FOR N=1 TO 128
    'M=N'無意味なので書き直します。
    D(N)=Asc(Mid$(X$,N,1))
NEXT
FOR N=1 TO 128
    'M=N+128'無意味なので書き直します。
    D(N+128)=Asc(Mid$(Y$,N,1))
NEXT
Close #1
Goto 1210

1210 '略。
STBAA=D(147)<<8+D(148)'<<記号はシフト演算といって、2のべき乗となる数を掛けるのに都合がいいので書き直しています。ヘルプ参照。
DTBAA=D(150)<<16+D(151)<<8+D(152)
X1=D(153)
X2=D(154)
X3=D(155)
X4=D(156)
SIGN=(-1)^((X1 AND 128)/128)'言い忘れましたが、論理演算をする時は使う変数は整数型(この場合適切なのはByte型)で宣言してください。
'例
'Dim X1 As Byte
EXPO1=((X1 AND 127)*2+(X2 AND 128)/128)-127
EXPO#=2^EXPO1
FRAC#=(X2 OR 128)/128+X3/(128*256)+X4/(128*256*256)
SCL#=SIGN*EXPO#*FRAC#
IF Abs(RE#)<=1E-38 THEN RE=0' Then RE#=0 だと思います。
SCLAA=SCL#/10^6
GOTO 1350
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
7
記事: 473
登録日時: 2005年5月31日(火) 18:51
お住まい: 新潟県
連絡する:

Re: DimやGetの書き方

#3 投稿記事 by 7 »

> ・Dim () As Double のカッコ内に文字を使いたいがどうしたらいいか
>  1710 2320 2930行目
DIM DD(DTB+300) As Doubleってのはつまり動的に変数を確保したいっていうことですよね?。色々と考える必要が有ってたぶん難しいと思いますが以下のようにすると可能です。

コード: 全て選択

DIM DD As *Double

	' この部分が肝心になります。
	DD=calloc(SizeOf(Double)*(DTB+300))

	' DD[DTB+300]までアクセス可能
	DD[0]=0.1
	DD[1]=0.2

	free(DD)
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

#4 投稿記事 by konisi »

元がどう動いていたかはわからないので何ともいえませんが、取り敢えずコンパイルが通る形に書き換えが完了しました。不恰好だけどインデントとか変更したのとコンパイル通るのとが終わっているので、他の人にも難なく手伝えると思います。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
斉藤 圭佑

Re: DimやGetの書き方

#5 投稿記事 by 斉藤 圭佑 »

対応策を丁寧にアドバイスしていただき、ありがとうございます。

konisiさんが作成されたプログラムをこちらで編集せずそのまま走らせてみたのですが、実行画面は固まってしまい、ソース画面には
“スレッド(&HF64)でアクセス違反がありました(EPI=&H00402518)”
と表示が出てしまい実行ができませんでした。

また、konisiさんと7さんのアドバイスを元に自分なりにプログラムを作ってみました。
konisiさんと7さんのアドバイスのおかげでコンパイル時のエラーはなんとか消えたのですが、実行を行う際に実行画面が固まってしまいます。プログラムのどこかがおかしいのでしょうか。

具体的にどこがおかしいかも知れないというところが判らないので質問が漠然としてしまい申し訳ありません。

以下にプログラム上でOpenされるファイルと、MS-DOS上で正常に実行された場合に書き出されるデータをアップしています。
http://briefcase.yahoo.co.jp/bc/keisukk ... http%3a//b

自分なりに作成したプログラムソースです。
斉藤 圭佑

Re: DimやGetの書き方

#6 投稿記事 by 斉藤 圭佑 »

対応策を丁寧にアドバイスしていただき、ありがとうございます。

konisiさんが作成されたプログラムをこちらで編集せずそのまま走らせてみたのですが、実行画面は固まってしまい、ソース画面には
“スレッド(&HF64)でアクセス違反がありました(EPI=&H00402518)”
と表示が出てしまい実行ができませんでした。

また、konisiさんと7さんのアドバイスを元に自分なりにプログラムを作ってみました。
konisiさんと7さんのアドバイスのおかげでコンパイル時のエラーはなんとか消えたのですが、実行を行う際に実行画面が固まってしまいます。プログラムのどこかがおかしいのでしょうか。

具体的にどこがおかしいかも知れないというところが判らないので質問が漠然としてしまい申し訳ありません。

以下にプログラム上でOpenされるファイルと、MS-DOS上で正常に実行された場合に書き出されるデータをアップしています。
http://briefcase.yahoo.co.jp/bc/keisukk ... http%3a//b

自分なりに作成したプログラムソースです。
斉藤 圭佑

Re: DimやGetの書き方

#7 投稿記事 by 斉藤 圭佑 »

対応策を丁寧にアドバイスしていただき、ありがとうございます。

konisiさんが作成されたプログラムをこちらで編集せずそのまま走らせてみたのですが、実行画面は固まってしまい、ソース画面には
“スレッド(&HF64)でアクセス違反がありました(EPI=&H00402518)”
と表示が出てしまい実行ができませんでした。

また、konisiさんと7さんのアドバイスを元に自分なりにプログラムを作ってみました。
konisiさんと7さんのアドバイスのおかげでコンパイル時のエラーはなんとか消えたのですが、実行を行う際に実行画面が固まってしまいます。プログラムのどこかがおかしいのでしょうか。

具体的にどこがおかしいかも知れないというところが判らないので質問が漠然としてしまい申し訳ありません。

以下にプログラム上でOpenされるファイルと、MS-DOS上で正常に実行された場合に書き出されるデータをアップしています。
http://briefcase.yahoo.co.jp/bc/keisukk ... http%3a//b

自分なりに作成したプログラムソースです。
斉藤圭佑
記事: 5
登録日時: 2006年10月31日(火) 19:40
お住まい: 神奈川

すいません。

#8 投稿記事 by 斉藤圭佑 »

同じ内容を3回も送信してしまいました。
また、ログインせずに送信してしまったので名前の下に“ゲスト”がついてしまいました。
以後気をつけます。
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

#9 投稿記事 by konisi »

変数名の直後に#や%、$を付ける事があるのは変数の型を識別するためのもので、RE#とREをAB上で区別する必要は無いはずです。


追伸
こちらでは(自分で書いた側の物は)正常に動いてますが・・・?
OS:WinXP SP2 Home
CPU:Intel Pentium D 3.0GHz
BIOS:FUJITSU製
Shell:Explorer
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
斉藤圭佑
記事: 5
登録日時: 2006年10月31日(火) 19:40
お住まい: 神奈川

#10 投稿記事 by 斉藤圭佑 »

私の方でも確認しましたが、AB上でREとRE#は区別する必要はありませんでした。失礼しました。

konisiさんの作成されたプログラムをこちらで走らせてみたところ、確かにエラーもなく正常に動作します。

しかし、元のプログラムであったBASICで実行させて書き出された結果と、
BASICを書き換えたActiveBasicで実行させて書き出された結果とが違ってしまいます。こちらで調査しているのですがなかなか解決の糸口が見つかりません。

BASIC上で実行させて書き出された結果は、前回投稿した際にリンクを貼ったものと同じですが、以下にアップします。
http://briefcase.yahoo.co.jp/bc/keisukk ... http%3a//b

また、X領域とY領域にの割り当てについてですが、過去に書いた人のプログラム説明を見るとX、Y両方とも必要な感じがするのですが。。。
以下に今回のプログラムをBASICで書いた人が書いたプログラム説明の一部を示します。


1060~1070 行
実験データの記録されたランダムファイル”DAT3-14.FRK”をオープンし,ランダムファイル用バッファ# 1 の設定を行う.領域X$に128byte を割り当て,領域Y$に128byte を割り当てる.

1090~1180 行
ランダムファイル用バッファ# 1 に読み込ませた実験データを配列D へ書き込む. ループを128 ずつに分割するのは,スケールファクタ算出プログラムと同様,ヘッダーブロックと拡張ヘッダーブロックに分割するためである.ヘッダーブロックの大きさは128byte で固定されており,配列D(1)~D(128) には領域X$のデータが読み込まれ,ヘッダーブロックの情報が読み込まれる.また,拡張ヘッダファイルの情報は,領域Y$に書き込まれた128byte の情報となり,配列D(129)~D(256) に読み込まれる.
マティ
記事: 161
登録日時: 2005年8月23日(火) 00:15
お住まい: 沖縄県
連絡する:

#11 投稿記事 by マティ »

斉藤圭佑さん問題は解決しましたか?
まだ、問題を抱えているのなら、変数の定義をもう一度見直してください。
あと、リンクを張ったデータで元データと変換後のデータは同一のものでしょうか?
(こちらでうまくいかないので質問しました)

ここからは技術補足
konisi さんが書きました:変数名の直後に#や%、$を付ける事があるのは変数の型を識別するためのもので、RE#とREをAB上で区別する必要は無いはずです。
ActiveBasicでは、変数定義時に#,%,$の意味は無くただの変数名として認識します。

しかし、マイクロソフト系のBasicでは、#,%,$にも変数の定義の意味があります。
たとえば

コード: 全て選択

Dim D$
	D ="Test Data"
	Print D$

コード: 全て選択

Dim D As String
	D$="Test Data"
	Print D
は同じ結果になりますが、ActiveBasicでは変数が無いためコンパイルエラーになります。

結果的には、

コード: 全て選択

Dim D  As String
Dim D$ As String
	D$="Test Data"
	Print D
と変数を定義してコンパイルエラーを取りますが
変数D$に文字列を設定しているので、変数DをPrintしても何も表示されません!

このような、重複宣言がたくさんありますので、答えが一致しないと思われます。
斉藤圭佑
記事: 5
登録日時: 2006年10月31日(火) 19:40
お住まい: 神奈川

#12 投稿記事 by 斉藤圭佑 »

マティさん

残念ながら未だ問題は解決できていません。
マティさんのアドバイス通り、変数の定義から確認してみます。
また、リンクを貼ったデータ

「DAT3-14.FRK」 : 入力ファイル
「DAT-GAA.DAT」 : 出力ファイル
「DAT-GAB.DAT」 : 出力ファイル
「DAT-GBB.DAT」 : 出力ファイル
「GAIN.DAT」 : 出力ファイル

についてですが、こちらは全てPC9821Xn(MS-DOS上)のN88BASICで走らせた正しいデータです。
このデータと同様のものをDOS/V上のABで出力したいのですが。。。
未だ出力ファイル「DAT-GAA.DAT」、「DAT-GAB.DAT」、「DAT-GBB.DAT」、「GAIN.DAT」全て正しいデータと一致していない状態です。

現在、手立てとして考えているのは

コード: 全て選択


Open "DAT3-14.FRK" As #1
Field #1,256
Get #1,,X$
For N=1 To 256
D(N)=Asc(Mid$(X$,N,1))
Next
の部分を

コード: 全て選択


Open "DAT3-14.FRK" As #1
Field #1,128
Get #1,1,X$
Get #1,2,Y$
For N=1 To 128
D(N)=Asc(Mid$(X$,N,1))
Next
For N=1 To 128
D(N)=Asc(Mid$(Y$,N,1))
Next
のようにX$領域とY$領域で分けて表現するところは分けて記述して試しているところです。
X$領域にはD(1)~D(128)、Y$領域にはD(129)~D(256)と割り振るとN88BASICで作成した者の資料に書いてあったのでその通りにしようと思っているのですが、そもそもこの書き方であってるのかも不安です。
ar
記事: 4
登録日時: 2006年7月10日(月) 22:57
お住まい: 埼玉県

#13 投稿記事 by ar »

昨日、マティさんが確認しておられますが、本当に「DAT-GAB.DAT」は正しいものなのでしょうか?

プログラムを見ると、GABのデータ部分は「DAT3-14.FRK」の&h1B00から始まっているのだと思います。
また、該当箇所を実部と虚部の2変数で各4byteづつ読み込んでいるものと思います。
そこで実際に「DAT3-14.FRK」を見ると、
&h1B00~&h1B07が、&h00000000と&h00000000で、両変数とも0。
&h1B08~&h1B0Fが、&hC5C3A3AEと&hC6194685で、両変数とも負の値になり、SCLABを掛けたとしても最低同符号になるはずではないでしょうか。
ところが「DAT-GAB.DAT」ではw=0.25の値は正と負の数の異符号になっており、アップされたものが異なっているのではないかと思う次第です。
マティ
記事: 161
登録日時: 2005年8月23日(火) 00:15
お住まい: 沖縄県
連絡する:

#14 投稿記事 by マティ »

私もarさんと同じ見解です。

斉藤圭佑さん、N88BASICに以下の文を追加してサンプルファイルを作成していただけませんか?

コード: 全て選択

Print #2,Hex$(X1) & Hex$(X2) & Hex$(X3) & Hex$(X4) 
Print #2,Hex$(X5) & Hex$(X6) & Hex$(X7) & Hex$(X8) 
追加するのは、既存のPrint #2の直前にお願いします。
河川屋

Re: DimやGetの書き方

#15 投稿記事 by 河川屋 »

元プログラムがQuickBasicかN88BasicかFBasicかによって動きが変わります。

> プログラムの内容の概要は「バイナリデータをテキストデータに変換する」

まず、この部分が問題です。
バイナリデータとは、当然数値データとすると、
どこが整数でどこが実数か。また、実数バイナリとして、内部表現はどうなっているか?
これがわからないことには何もできません。
※ちなみに、実数で可能性があるのは、
  ・IEEE754形式(QuickBasic)
  ・MBFバイナリ(本家N88Basic,GW-BASIC)
  ・MBFバイナリモトローラ形式(F-basic。MBFバイナリとバイト順が逆。)
以上、どれですか?
いずれにせよ、まず文字型から数値型へ自力変換しないことにはどうにもなりません。

> 1260 SIGN=(-1)^((X1 AND 128)/128)
> 1270 EXPO1=((X1 AND 127)*2+(X2 AND 128)/128)-127
> 1280 EXPO=2^EXPO1
> 1290 FRAC=(X2 OR 128)/128+X3/(128*256)+X4/(128*256*256)
> 1300 SCL=SIGN*EXPO*FRAC
これが文字型から数値型へ自力変換する部分にあたり、バイナリ形式により式が変わり、

IEEE754の場合:(非正規数には対応していない。)
SIGN=(-1)^((X4 AND 128)/128)
EXPO1=((X4 AND 127)*2+(X3 AND 128)/128)-127
EXPO=2^EXPO1
FRAC=1+(X3 AND 127)/128+X2/(128*256)+X1/(128*256*256)
SCL=SIGN*EXPO*FRAC

MBFバイナリの場合:
SIGN=(-1)^((X3 AND 128)/128)
EXPO1=X4-129
EXPO=2^EXPO1
FRAC=1+(X3 AND 127)/128+X2/(128*256)+X1/(128*256*256)
SCL=SIGN*EXPO*FRAC

F-BASIC(モトローラ流のMBFバイナリ)の場合:
SIGN=(-1)^((X2 AND 128)/128)
EXPO1=X1-129
EXPO=2^EXPO1
FRAC=1+(X2 AND 127)/128+X3/(128*256)+X4/(128*256*256)
SCL=SIGN*EXPO*FRAC

のいずれかになる可能性が高いです。これで動く保証は無いけど。
※式のチェックは、QuickBqsic(PC9801用)で行なったものであり、
 ActiveBasicでチェックしたわけではない。

> 1060 OPEN "DAT3-14.FRK" As #1 ' FILE NAME
QuickBasicなどでは、
OPEN "R",#1,"DAT3-14.FRK",256  または
OPEN "DAT3-14.FRK" AS #1 LEN=256
とすれば、任意のレコード長のランダムファイルがOPENできる。デフォは256。
N88Basicは256Byte固定。(正確には、basic起動時に指定可能。)
ActiveVasicはマニュアル見てもワケわかんない。
まず、output/input等を指定しないときはオールアクセス可とあって、ランダムとは書かれていない
ため、どう動くのか不明。で、レコード長の指定方法不明、デフォの長さも未記載。

> 1070 FIELD #1,128 As X$ ' DATA BUFFER
> 1071 FIELD #1,128 As Y$
QuickBasic、N88Basic、FBasic共通で、こう書いた場合の意味は、
レコード長の最初の128byteにX$を割り当てる。
レコード長の最初の128byteにY$を割り当てる。
となるから、結局、 X$とY$には同じ領域が割り当てられる。
以上より、下記のような割付も可能となる。

FIELD #1,4 as X$(1)
FOR I=2 TO 32
FIELD #1,(I-1)*4 AS DUMMY$,4 as X$(I)
NEXT
これで、X$(i)に4byteきざみでバッファが割り当てられる。

追記 コレは、元プログラムでは
FIELD #1,128 AS X$,128 AS Y$
と、1行に書かれていたものと思われる。
(N88BASICの最大文字列長は255Biteなので、どうしても2変数が必要となる。)

ActiveVasicのマニュアルには、
Field #filenumber, fieldbyte
とあり、変数名をどうやって割り当てるのか書かれていない。
(ひっとすると、fieldbyteがレコード長と対応し、
GET #1,recode,StrBuffer のStrBufferがFieldに割り当てる変数?
 じゃあFieldに複数の変数を割り当てたい場合は構造体を使う?
 このへん、マニュアル不備です! マニュアル&サンプルがあまりに酷いので実験する気力なし。)


結論:
この手のプログラムを組むには、QuickBasicが便利。(WIN95に英語版が入っているから入手は困難ではないはず。)
MBFバイナリ、IEEE754のどちらも数値に変換する関数を持っているため。
ActiveBasicにはバイナリ-数値の変換関数は存在せず。
(IEEE754なら、GETWORDで単精度変数に強引に送り込めば何とかなりそうだが、マナー悪すぎのためやめたほうがいいと思う。)
返信する