StackOverflowExceptionについて
投稿者 まだまだ  (中学生)
投稿日時
2009/8/27 06:25:17
こんにちは
すみません、答えではないのですが、最大公約数は
「GCD」ではなく「GCM」ではなかったでしょうか?
答えではなくてすみません。
すみません、答えではないのですが、最大公約数は
「GCD」ではなく「GCM」ではなかったでしょうか?
答えではなくてすみません。
投稿者 トマト  (小学生)
投稿日時
2009/8/27 07:53:58
一応Yahoo!辞書で調べたのですが…。
投稿者 おおぎっち  (社会人)
投稿日時
2009/8/27 07:56:55
答えじゃありませんが気になったので
CCDもGCMもあってます。
ほかにはGCFとかいったりもします。
嗚呼、これだけですみません。
CCDもGCMもあってます。
ほかにはGCFとかいったりもします。
嗚呼、これだけですみません。
投稿者 刈谷勇  (社会人)
投稿日時
2009/8/27 22:19:55
こんにちは、トマトさん。
>分数のクラスを作っているのですが計算中にStackOverflowExceptionが発生します。
StackOverflowExceptionが発生する場所はどこで出ているのでしょうか?
また、提示していただいたプログラムのどのメソッドを呼んで、そのときの各変数等の値がどのようになっているのかを提示していただけないでしょうか?
※GetGCDはもっと簡単に書けるような気が・・・
>分数のクラスを作っているのですが計算中にStackOverflowExceptionが発生します。
StackOverflowExceptionが発生する場所はどこで出ているのでしょうか?
また、提示していただいたプログラムのどのメソッドを呼んで、そのときの各変数等の値がどのようになっているのかを提示していただけないでしょうか?
※GetGCDはもっと簡単に書けるような気が・・・
投稿者 るきお  (社会人)
投稿日時
2009/8/27 22:26:35
こんにちは。
現象が再現できるコードがないと回答しにくいです。
一般的には数学などのように同じ処理を何度も何度も繰り返す場合、
同じメソッドが何度も何度も入れ子上に呼び出されStackOverflowの例外が発生します。
次の例は、処理のないように意味はありませんがStackOverflowが発生するシンプルな例です。
この例外を回避する代表的な方法は、
1.ロジックを見直して再帰が発生しないようにする。→再帰ではなくループを使う。
3.求める精度を低くする。→再帰回数カウント、求める値の桁数のチェックなどをして処理の停止条件とする。
3.StackOverflowの例外をCatchする。
といったところです。
現在では3は推奨されていないようです。
現象が再現できるコードがないと回答しにくいです。
一般的には数学などのように同じ処理を何度も何度も繰り返す場合、
同じメソッドが何度も何度も入れ子上に呼び出されStackOverflowの例外が発生します。
次の例は、処理のないように意味はありませんがStackOverflowが発生するシンプルな例です。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Integer
i = AddOne(0)
End Sub
Private Function AddOne(ByVal value As Integer) As Integer
value += 1
Return AddOne(value)
End Function
この例外を回避する代表的な方法は、
1.ロジックを見直して再帰が発生しないようにする。→再帰ではなくループを使う。
3.求める精度を低くする。→再帰回数カウント、求める値の桁数のチェックなどをして処理の停止条件とする。
3.StackOverflowの例外をCatchする。
といったところです。
現在では3は推奨されていないようです。
投稿者 トマト  (小学生)
投稿日時
2009/8/28 02:47:32
よくよくコードを見てみるとGetGCDに無駄がありそうです。
これから、修正してみます。
これから、修正してみます。
投稿者 トマト  (小学生)
投稿日時
2009/8/28 03:08:32
今、GetGCDを改良してみました。
結果は失敗です。
というよりも変な現象が起きました。
テスト用コード
これを実行すると、GetGCDの"If Not IsDecimal(inting) Then"の行で呼び出しているIsDecimalの "For Each c As Char In Nomber.ToString"の行で発生しました。
でも変です。
ToDoubleではReduceは呼び出さないはずです。
IsDecimalのローカル
もっと探ってみました。
すると、Denominatorという分母のプロパティのSetの中のReduce()の背景の色が変わっていました。
どこからも呼び出していないのに・・・。不思議です。
Public Function GetGCD(ByVal Int1 As Integer, ByVal Int2 As Integer) As Integer
'小さいほうを探す
Dim Mini As Integer = Math.Min(Int1, Int2)
Dim Int1_List As New List(Of Integer)
Dim OKList As New List(Of Integer)
Dim inting As Double
'Int1を確認
For i As Integer = 1 To Mini
inting = Int1 / i
If Not IsDecimal(inting) Then
Int1_List.Add(i)
End If
Next
'Int2を確認
For i As Integer = 1 To Mini
inting = Int2 / i
If Not IsDecimal(inting) AndAlso Int1_List.Contains(i) Then 'ここを改良しました。
OKList.Add(i)
End If
Next
Return OKList(OKList.Count - 1)
End Function
結果は失敗です。
というよりも変な現象が起きました。
テスト用コード
Sub Main()
Application.EnableVisualStyles()
Dim f As New Fraction(5, 87)
MsgBox(f.ToDouble)
End Sub
これを実行すると、GetGCDの"If Not IsDecimal(inting) Then"の行で呼び出しているIsDecimalの "For Each c As Char In Nomber.ToString"の行で発生しました。
でも変です。
ToDoubleではReduceは呼び出さないはずです。
IsDecimalのローカル
IsDecimal False
Nomber 1.25
もっと探ってみました。
すると、Denominatorという分母のプロパティのSetの中のReduce()の背景の色が変わっていました。
どこからも呼び出していないのに・・・。不思議です。
投稿者 トマト  (小学生)
投稿日時
2009/8/28 03:47:34
解決しました。まだちょっとしかテストしていませんが。
ここでDenominatorにアクセスして無限にループしていたみたいです。
''' <summary>約分をします。</summary>
Protected Friend Sub Reduce()
Dim gcd = GetGCD(Me.Denominator, Me.Numerator)
Me._denominator \= gcd 'この行と
Me._numerator \= gcd 'この行が原因でした。
End Sub
ここでDenominatorにアクセスして無限にループしていたみたいです。
分数のクラスを作っているのですが計算中にStackOverflowExceptionが発生します。
MSDNによると「入れ子のメソッド呼び出しが多すぎて実行スタックがオーバーフローすると、 StackOverflowException 例外がスローされます。」とのことです。
これを回避する方法はありませんか?
コードを載せておきます。
ちょっと読みにくくなってしまいました。