Forループ中での停止
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2011/12/6 18:11:01
> 2重Forループの途中でプログラムが
> オーバーフローエラーを起こして停止してしまいます。
> ゼロ割はしていないようなのですが、
ゼロ割り以外でも、そのエラーが出ることはあります。
エラーが発生した時の各変数の値を調べてみてください。
たとえば、2 つの Integer 型 の値を足したり掛けたり乗じたりすると、
結果が Integer で表される範囲を超えてしまい、エラーとなりえます。
> ゼロ割の可能性を調べるために、
ゼロ割についていえば、その結果は以下の 4 種に分類されます。
> i1(配列1), j1(配列2), val(i1,j1)(値)
> i1(配列1), j1(配列2), x(i1)(座標1), y(j1)(座標2), val(i1,j1)(値)
VB には「Val 関数」がありますので、val という名の配列の利用は避けた方が無難です。
(Val という名にしても、実行結果そのものには影響を与えないのですけれどね)
> また、オーバーフローエラーは
> 解決出来るものでしょうか?
再現性があるようですし、原因さえ突き止めれば回避策も見えてくるでしょう。
> オーバーフローエラーを起こして停止してしまいます。
> ゼロ割はしていないようなのですが、
ゼロ割り以外でも、そのエラーが出ることはあります。
エラーが発生した時の各変数の値を調べてみてください。
たとえば、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 の精度で行えるため、値を代入する前に、計算処理の段階でエラーとなります。
変数 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」
・/ 演算子にて 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
としてデバッグ実行すれば例外が発生した行が分かるので
その辺をよくみるとよいと思います。
ループ
Catch ex as Exception
Console.WriteLine(ex.ToString)
End Try
としてデバッグ実行すれば例外が発生した行が分かるので
その辺をよくみるとよいと思います。
投稿者 ikex  (社会人)
投稿日時
2011/12/8 09:33:17
魔界の仮面弁士 様、shu 様
ご助言ありがとうございます。
早速試させていただきます。
また、valが組み込み関数として存在することは
初めて知りました。
shu様が仰るとおり、
今まで問題なかったために気付きませんでした。
ご助言ありがとうございます。
早速試させていただきます。
また、valが組み込み関数として存在することは
初めて知りました。
shu様が仰るとおり、
今まで問題なかったために気付きませんでした。
投稿者 ikex  (社会人)
投稿日時
2011/12/8 16:23:41
魔界の仮面弁士 様、shu 様
ありがとうございました。
無事解決いたしました。
ループ中に組み込み関数の引数の型が
一部不適切でした。
以前のプログラムのコピーを修正して用いていたのですが、
今まで問題なく動いていたので
気付きませんでした。
ありがとうございました。
ありがとうございました。
無事解決いたしました。
ループ中に組み込み関数の引数の型が
一部不適切でした。
以前のプログラムのコピーを修正して用いていたのですが、
今まで問題なく動いていたので
気付きませんでした。
ありがとうございました。
停止してしまう原因について質問です。
言語は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)
で停止していました。
この原因は何のでしょうか?
また、オーバーフローエラーは
解決出来るものでしょうか?