Forループ中での停止

タグの編集
投稿者 ikex  (社会人) 投稿日時 2011/12/6 17:40:21
Forループ中でプログラムが
停止してしまう原因について質問です。
言語はVisual Basic 2010 expressです。

2重Forループの途中でプログラムが
オーバーフローエラーを起こして停止してしまいます。
ゼロ割の可能性を調べるために、
どこで止まっているかをファイルに書き出して調べました。
ゼロ割はしていないようなのですが、
そこで不思議な事が起こりました。
ファイルに
i1(配列1), j1(配列2), val(i1,j1)(値)
i1(配列1), j1(配列2), x(i1)(座標1), y(j1)(座標2), val(i1,j1)(値)
をそれぞれ書き出させたところ、
ループが停止している位置が異なりました
(変化しているのは、この書き出し部分だけです)。
具体的にはi1max=35, j1max = 70で
前者が(i1, j1) = (18,4)
後者が(i1, j1) = (34, 3)
で停止していました。
この原因は何のでしょうか?

また、オーバーフローエラーは
解決出来るものでしょうか?

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2011/12/6 18:11:01
> 2重Forループの途中でプログラムが
> オーバーフローエラーを起こして停止してしまいます。
> ゼロ割はしていないようなのですが、

ゼロ割り以外でも、そのエラーが出ることはあります。
エラーが発生した時の各変数の値を調べてみてください。

たとえば、2 つの Integer 型 の値を足したり掛けたり乗じたりすると、
結果が Integer で表される範囲を超えてしまい、エラーとなりえます。

Dim a As Integer = 123456789
Dim b As Integer = 987654321
Dim c As Long = a * b   'エラー! 
Dim d As Long = CLng(a) * CLng(b)  'これならOK! 

上記の場合、a×b を演算した結果は 121,932,631,112,635,269 です。
変数 c は Long 型で、その最大値 9,223,372,036,854,775,807 を下回っているため
一見すると格納できるようにも思えますが、Integer × Integer という計算は
Integer の精度で行えるため、値を代入する前に、計算処理の段階でエラーとなります。



> ゼロ割の可能性を調べるために、
ゼロ割についていえば、その結果は以下の 4 種に分類されます。

★DivideByZeroException になる例
 ・/ 演算子にて Decimal のゼロで割った場合
 ・\ 演算子でゼロ割りした場合
 ・Mod 演算子でゼロ割りした場合

★エラーにならない例
 ・Double 型や Single 型としてゼロ割りされた場合(±∞になる)

★OvreflowException になる例
 ・ゼロ割りして無限大になった値を Integer 変数等に代入した場合

★コンパイルエラーになる例
 ・BC30542:評価段階で DivideByZeroException が検出される場合「例:Dim a As Double  = 10 \ 0」
 ・BC30439:評価段階で OvreflowException     が検出される場合「例:Dim a As Integer = 10 / 0」



> i1(配列1), j1(配列2), val(i1,j1)(値)
> i1(配列1), j1(配列2), x(i1)(座標1), y(j1)(座標2), val(i1,j1)(値)

VB には「Val 関数」がありますので、val という名の配列の利用は避けた方が無難です。
(Val という名にしても、実行結果そのものには影響を与えないのですけれどね)


> また、オーバーフローエラーは
> 解決出来るものでしょうか?
再現性があるようですし、原因さえ突き止めれば回避策も見えてくるでしょう。
投稿者 shu  (社会人) 投稿日時 2011/12/7 07:59:46
Try
    ループ
Catch ex as Exception
    Console.WriteLine(ex.ToString)
End Try

としてデバッグ実行すれば例外が発生した行が分かるので
その辺をよくみるとよいと思います。
投稿者 ikex  (社会人) 投稿日時 2011/12/8 09:33:17
魔界の仮面弁士 様、shu 様
ご助言ありがとうございます。
早速試させていただきます。

また、valが組み込み関数として存在することは
初めて知りました。
shu様が仰るとおり、
今まで問題なかったために気付きませんでした。
投稿者 ikex  (社会人) 投稿日時 2011/12/8 16:23:41
魔界の仮面弁士 様、shu 様
ありがとうございました。

無事解決いたしました。
ループ中に組み込み関数の引数の型が
一部不適切でした。
以前のプログラムのコピーを修正して用いていたのですが、
今まで問題なく動いていたので
気付きませんでした。

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