2010-12-20 157 views
1

在下面的代码中它应该乘以2个数字。它适用于3位和3位以下的数字,但当我给出4位数或更大的数字时,会产生运行时错误:stackoverflow exception was unhandled。我已经评论了问题出在哪里。我认为问题是在int中定义变量,并且长时间更改它们,但问题仍然存在。错误在哪里?stackoverflow异常未处理

编辑: 现在,什么你怎么看待这个问题它没有做任何事情

 public long Prod2(long u, long v) 
    { 
     var numbers = textBox7.Text.Split(',').Select(p => long.Parse(p)).ToArray(); 
     int n = Math.Max((int)Math.Floor(Math.Log10(u) + 1),(int)Math.Floor(Math.Log10(v) + 1));   
     int threshold = 3; 

     if (u == 0 || v == 0) 
     { 
      return 0; 
     } 
     else if (n <= threshold) 
     { 
      return u * v; 
     } 
     else 
     { 
      int m = (int)Math.Ceiling(n/2.0); 

      int x = (int)(u/Math.Pow(10, m)); 
      int y = (int)(u % Math.Pow(10, m)); 
      int w = (int)(u/Math.Pow(10, m)); 
      int z = (int)(v % Math.Pow(10, m)); 

      long r = Prod2(x + y, w + z); 
      long p = Prod2(x, w); 
      long q = Prod2(y, z); 

      return p * (long)Math.Pow(10, 2 * m) + (r - p - q) * (long)Math.Pow(10, m) + q; 
      long result = Prod2(numbers[0], numbers[1]); 
      textBox1.Text = result.ToString(); 
     } 
    } 
+0

@arash - 如果你能解释一下,我很乐意提供帮助*这种方法试图做什么*做*? – TheCloudlessSky 2010-12-20 13:35:16

+0

m是一个3位数字? – mingos 2010-12-20 13:35:57

+1

stackoverflow异常不是由算术运算引起的。这是因为你的递归不会因为某种原因而停止。 – nan 2010-12-20 13:39:22

回答

2

编辑:我已经完全翻译成你的书描述的算法:

public long Prod2(long u, long v) 
{ 
    int n = Math.Max((int)Math.Floor(Math.Log10(u) + 1), (int)Math.Floor(Math.Log10(v) + 1)); 
    int threshold = 3; 

    if(u == 0 || v == 0) 
    { 
     return 0; 
    } 
    else if(n <= threshold) 
    { 
     return u * v; 
    } 
    else 
    { 
     int m = (int)Math.Ceiling(n/2.0); 

     int x = (int)(u/Math.Pow(10, m)); 
     int y = (int)(u % Math.Pow(10, m)); 
     int w = (int)(u/Math.Pow(10, m)); 
     int z = (int)(v % Math.Pow(10, m)); 

     long r = Prod2(x + y, w + z); 
     long p = Prod2(x, w); 
     long q = Prod2(y, z); 

     return p * (long)Math.Pow(10, 2 * m) + (r - p - q) * (long)Math.Pow(10, m) + q; 
    } 
} 

为了得到正确的结果,你会调用这个方法从某些其他方法是这样:

void Main() 
{ 

    // Call the method and store the result in variable 'r'. 
    long r = Prod2(1234, 5678); 
    Console.WriteLine(r); 

    ///////////////////////////////// 
    // 
    // OR - In your case read from textBox7 and then store the result in textBox1  
    // 
    ///////////////////////////////// 
    var numbers = textBox7.Text.Split(',').Select(p => long.Parse(p)).ToArray(); 
    long result = prod2(numbers[0], numbers[1]); 
    textBox1.Text = result.ToString(); 
} 

因此,在你的事件处理程序,例如用于button1,你会做拨打电话:

public void button1_Click() 
{ 
    var numbers = textBox7.Text.Split(',').Select(p => long.Parse(p)).ToArray(); 
    long result = prod2(numbers[0], numbers[1]); 
    textBox1.Text = result.ToString(); 
} 

不要修改Prod2我有,只是你的代码粘贴。这样,Prod2会进行计算,然后您的button1_Click控制输入以及如何处理输出

+0

的评论谢谢,但它与我输入的每个数字,它说不到3位数:2 – Arash 2010-12-20 14:45:45

+0

@arash - 好吧 - 我把那些放在那里,所以你可以看到递归发生。删除或注释掉任何'Console.WriteLine'或'MessageBox.Show'行,以便它*没有输出。 – TheCloudlessSky 2010-12-20 14:48:58

+0

好的,当它不提供输出我能用这个代码做什么? – Arash 2010-12-20 15:06:25

2

简单地说你有一个潜在的(不同的输入)情况:

function bigzarb() 
{ 
    bigzarb() 
} 

只要textBox7中的数字> 3,即一个未关闭的递归循环,这将不可避免地成为一个栈溢出。

在有问题的线路上设置断点,您很快就会看到问题。不知道你的方法是干什么的(我不认识这个算法),我无法帮忙清理它,但是第一步可能是有条件的从条件返回。但是,我也看到你在输入参数uv被使用之前覆盖输入参数,所以也许你在算法中犯了错误?

+0

++这是正确的答案,另请参阅我的答案为具体行 – 2010-12-20 13:48:33

+0

谢谢先生,它乘以两个数字,用户在textbox7中写入两个数字,然后它乘以数字,为3和少于3位数字,它做一般乘法,并且对于大于4位的数字,它获得输入数字(n)的最大位数,然后除以2并将其放入m中,然后将u除以10^myy和w并且z如此做。在bigzarb(x, w)它用x和v替换u用w和乘以10^m再次bigzarb(x,z)+ bigzarb(w,y)... – Arash 2010-12-20 14:00:41

+0

@arash哇,慢下来......第一件事,当你说“少于3位”请再看看这些行... int intn = Convert.ToInt32(n);如果(intn <= 3)...这不是“多少数字”,而是“这个数字小于或等于3”(数值不是长度) – 2010-12-20 14:04:51

0

Pow方法返回double,所以我认为你的x,y,z,w和z应该声明为double。

3

您正在进入一个无限递归循环在这一点上

long result = bigzarb(x, w) * Math.Pow(10, m) + (bigzarb(x, w) + bigzarb(w, y)) * Math.Pow(10, m) + bigzarb(y, z);///here 
    textBox1.Text = result.ToString(); 

我注意到这条线只有当intn > 3执行,所以也许你有一个逻辑错误吗?

更新:阅读您的意见后,我可以看到这个测试的目的是说“如果这个字符串的长度为< = 3,那么......”的时候,其实书面它实际上是说“如果此转换后的字符串的值为< = 3,则...“

+0

我应该怎么做才能在运行时停止循环1time – Arash 2010-12-20 13:49:07

+2

@Saeed报告的错误是StackoverflowException而不是OverflowException,请参阅http://msdn.microsoft.com/en-us/library/system.overflowexception.aspx和http://msdn.microsoft.com/en-us/library/system.stackoverflowception.aspx – 2010-12-20 13:51:20

+0

是的你是对的+ – 2010-12-20 13:56:36

0

您正在为递归调用获取”StackoverFlow“。它更好地模拟代码中发现的洞。我建议你改变逻辑。

static int callStack = 0;

public double bigzarb(long u, long v) 
    { 
     callStack++; 
     ............ 
     ............