オーバーフローについて。

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

オーバーフローについて。

#1 投稿記事 by konisi »

ABで、直前の計算(加算)でオーバーフローしたかどうかを判断する関数ってありましたっけ?
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
tak
記事: 162
登録日時: 2005年5月31日(火) 07:49

Re: オーバーフローについて。

#2 投稿記事 by tak »

> ABで、直前の計算(加算)でオーバーフローしたかどうかを判断する関数ってありましたっけ?

たぶんそのような関数はないと思います。
だから自分で作ってしまいましょう(あるいは山本様にお願いするというのもアリです)。

作ってしまうとは言ったものの、これが一筋縄ではいかない模様。
(32bit) + (32bit) の計算ならば結果を 64bit 変数に格納し、上位 32bit が 0 または &HFFFFFFFF かどうかを判断すればよいとおもいます。
しかしこれでは、オペランドの片方(または両方)が 64bit の場合に破綻します。また符号ありと符号なしを混ぜたときにイヤなことになるかも。


いろいろ考えた結果 http://www.activebasic.com/forum/viewtopic.php?t=308 からヒントを得ました。

CPU の内部には、計算結果に関するあれこれを保存しておくためのフラグ記憶域 (EFLAGS) があります。
そこに直接アクセスすれば最も確実にオーバーフローを検査できるというわけです。

言うは易く行うは難し。ABにはインラインアセンブラがないのでハンドアセンブルでかなり苦労しました。

コード: 全て選択

' Constants of Status Flags
Const EFLAGS_CF = &H1       ' Carry Flag        加算(減算)で桁上がり(桁借り)が発生
Const EFLAGS_PF = &H4       ' Parity Flag       最下位バイトのパリティ
Const EFLAGS_AF = &H10      ' Adjust Flag       調整フラグ(BCD 命令で使用)
Const EFLAGS_ZF = &H40      ' Zero Flag         計算結果がゼロ
Const EFLAGS_SF = &H80      ' Sign Flag         計算結果の符号
Const EFLAGS_OF = &H800     ' Overflow Flag     オーバーフローが発生

Dim __gf = &HC3589C As DWord
Dim __sf = &HE1FF9D59 As DWord
Dim GetEFLAGS As *Function() As DWord
Dim SetEFLAGS As *Sub(ByVal NewValue As DWord)
GetEFLAGS = VarPtr(__gf)
SetEFLAGS = VarPtr(__sf)
極限までサイズを縮めたので、関数本体が DWord 変数に収まりました。我ながらなかなか。

使用方法

コード: 全て選択

c = a + b
' 計算の直後に使用すること
If GetEFLAGS() And EFLAGS_OF Then
    MessageBox(NULL, "オーバーフローが発生", "テスト", MB_OK)
End If
コメント中にも書きましたが、計算の直後に GetEFLAGS() してください。
他の処理を間に挟むと、それにより EFLAGS が変化する恐れがあります。

データ実行防止機能で停止する場合や、プログラムの一般公開を考えている場合には VirtualAlloc() 等で適宜解決してください。
メモリページに実行権限が割り当てられていない場合、一般保護例外が発生する恐れがあります。


機械語なんて弄らないで済むのであればそれに越したことはないんですけどね。
他にももっといい方法がないか模索してみます。


[変更履歴]
2006/5/4 - 引用元 URL を新しいものに修正。
最後に編集したユーザー tak [ 2006年5月04日(木) 04:44 ], 累計 1 回
konisi
記事: 893
登録日時: 2005年7月25日(月) 13:27
お住まい: 埼玉県東松山市
連絡する:

ありがとうございました。

#3 投稿記事 by konisi »

とりあえず組んでみます。
ありがとうございました。
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。
Yoshi
記事: 27
登録日時: 2005年5月31日(火) 22:17
お住まい: 山口
連絡する:

#4 投稿記事 by Yoshi »

デバッグモードではうまくいきませんでした。
ActiveBasic ver 4.24
Windows2000sp4
Celeron(R) CPU 1.70GHz,256MB
今日も元気にABLife
tak
記事: 162
登録日時: 2005年5月31日(火) 07:49

#5 投稿記事 by tak »

> デバッグモードではうまくいきませんでした。
本当だ…全然使えないorz
どうしたものでしょうか。
代替案が思い浮かびませんから、現時点でこのアイデアは保留としておきますね。

# リリースコンパイルならちゃんと動くんですよね、何故か。
Yoshi
記事: 27
登録日時: 2005年5月31日(火) 22:17
お住まい: 山口
連絡する:

#6 投稿記事 by Yoshi »

> > デバッグモードではうまくいきませんでした。
> 本当だ…全然使えないorz
> どうしたものでしょうか。
> 代替案が思い浮かびませんから、現時点でこのアイデアは保留としておきますね。
>
> # リリースコンパイルならちゃんと動くんですよね、何故か。

直後に呼び出しているつもりでもデバッグモードではABのほうが変数の監視とかで何かやってるんでしょうかね。

足し算の部分まで機械語にしちゃうとか?
演算の種類、型は限定されてしまいますが。
今日も元気にABLife
返信する