2017-10-04 32 views
0

我正在编写一个程序,该程序的行为被设计为来自用户的单个文本输入的功能,而不是其他任何东西。没有使用系统时钟,没有引用外部文件,没有多线程。然而,当我运行程序时,程序执行时的控制流程与调试时不同,我认为在这种情况下应该是不可能的。运行和调试之间的不同控制流程

它不会自行编译,但这里是工作不正常功能:

static public Dictionary<ComplexNumber, int> getFactorization(ComplexNumber xGaussian) 
     { 
      Dictionary<ComplexNumber, int> factors = new Dictionary<ComplexNumber, int>(); 
      int sumOfRealAndImaginary = 2; 
      while (true) 
      { 
       Console.WriteLine(sumOfRealAndImaginary);//test 
       int realPart = sumOfRealAndImaginary/2; 
       int imaginaryPart = sumOfRealAndImaginary - realPart; 
       for (int i = 0; realPart - i >= 0;) 
       { 
        if ((realPart - i) * (realPart - i) + 
         (imaginaryPart + i) * (imaginaryPart + i) > 
         xGaussian.getRealPart().getNumerator() * 
         xGaussian.getRealPart().getNumerator() + 
         xGaussian.getImaginaryPart().getNumerator() * 
         xGaussian.getImaginaryPart().getNumerator()) 
        { 
         if (factors.ContainsKey(xGaussian)) 
          factors[xGaussian] += 1; 
         else 
          factors.Add(xGaussian, 1); 
         return factors; 
        } 
        ComplexNumber factor = 
         new ComplexNumber(realPart - i, imaginaryPart + i); 
        ComplexNumber quotient = (ComplexNumber)(xGaussian/factor); 
        quotient.getRealPart().reduce(); 
        quotient.getImaginaryPart().reduce(); 
        if (quotient.getRealPart().getDenominator() == 1 && 
         quotient.getImaginaryPart().getDenominator() == 1) 
        { 
         if (factors.ContainsKey(factor)) 
          factors[factor] += 1; 
         else 
          factors.Add(factor, 1); 
         xGaussian = (ComplexNumber)(xGaussian/factor); 
         continue; 
        } 
        factor = new ComplexNumber(realPart - i, -imaginaryPart - i); 
        quotient = (ComplexNumber)(xGaussian/factor); 
        quotient.getRealPart().reduce(); 
        quotient.getImaginaryPart().reduce(); 
        if (quotient.getRealPart().getDenominator() == 1 && 
         quotient.getImaginaryPart().getDenominator() == 1) 
        { 
         if (factors.ContainsKey(factor)) 
          factors[factor] += 1; 
         else 
          factors.Add(factor, 1); 
         xGaussian = (ComplexNumber)(xGaussian/factor); 
         continue; 
        } 
        ++i; 
       } 
       ++sumOfRealAndImaginary; 
      } 
     } 

的ComplexNumber类型的设计的行为方式复数数学做,但只限于土地及假想的部分是合理的,所以我将以与我在数学中的复数相同的方式键入ComplexNumber对象的值。为了简单起见,此版本的getFactorization()假定两个部分的分母均为1。

注意sumOfRealAndImaginary是如何初始化为2的,唯一改变的地方是它在while循环底部递增的地方。在调试模式下,当我传递getFactorization()值为3 + 4i并以足够中等的速度遍历代码时,它会在sumOfRealAndImaginary = 3时返回。这就是我所期望的。但是,当我运行程序时,也使用3 + 4i作为函数参数,直到sumOfRealAndImaginary = 126才会返回,如从while循环顶部的WriteLine()调用中可以看到的那样。特别是,while循环中的第一个if语句(其代码块包含函数的return语句)在运行时比调试时需要更多的传递来计算true。不仅对于预期的sumOfRealAndImaginary值为3,而且对于大于该值的每个值,它都应评估为真。另外,当我在调试模式下足够快地通过代码时,如果语句保持评估为false,直到我放慢速度,此时它在下一次传递时评估为true。所以看起来,if语句是否正确评估取决于代码执行的速度。什么会导致这种行为?

我可以列举出更多不同的意外行为,但也许这足以启动。

编辑:ComplexNumber类,按照PawełŁukasik的要求。分数是一个类似的类,它也是从Number类派生的,它是抽象的。

public class ComplexNumber : Number 
     { 
      Fraction m_real; 
      Fraction m_imaginary; 
      public ComplexNumber(Fraction real, Fraction imaginary) 
      { 
       m_real = real; 
       m_imaginary = imaginary; 
      } 
      public ComplexNumber(int real, int imaginary) 
      { 
       m_real = new Fraction(real, 1); 
       m_imaginary = new Fraction(imaginary, 1); 
      } 
      public Fraction getRealPart() 
      { 
       return m_real; 
      } 
      public Fraction getImaginaryPart() 
      { 
       return m_imaginary; 
      } 
      protected override Number add(Number number) 
      { 
       if (number is Fraction) 
       { 
        Fraction fraction = (Fraction)number; 
        return new ComplexNumber((Fraction)(m_real + fraction), m_imaginary); 
       } 
       ComplexNumber complexNumber = (ComplexNumber)number; 
       return new ComplexNumber((Fraction)(m_real + complexNumber.m_real), 
        (Fraction)(m_imaginary + complexNumber.m_imaginary)); 
      } 
      protected override Number subtract(Number number) 
      { 
       if (number is Fraction) 
       { 
        Fraction fraction = (Fraction)number; 
        return new ComplexNumber((Fraction)(m_real - fraction), m_imaginary); 
       } 
       ComplexNumber complexNumber = (ComplexNumber)number; 
       return new ComplexNumber((Fraction)(m_real - complexNumber.m_real), 
        (Fraction)(m_imaginary - complexNumber.m_imaginary)); 
      } 
      protected override Number multiply(Number number) 
      { 
       if (number is Fraction) 
       { 
        Fraction fraction = (Fraction)number; 
        return new ComplexNumber((Fraction)(m_real * fraction), 
         (Fraction)(m_imaginary * fraction)); 
       } 
       ComplexNumber complexNumber = (ComplexNumber)number; 
       return new ComplexNumber((Fraction)(m_real * complexNumber.m_real - m_imaginary * 
        complexNumber.m_imaginary), (Fraction)(m_real * complexNumber.m_imaginary + 
        m_imaginary * complexNumber.m_real)); 
      } 
      protected override Number multiply(int scalar) 
      { 
        return new ComplexNumber((Fraction)(m_real * scalar), 
         (Fraction)(m_imaginary * scalar)); 
      } 
      protected override Number divide(Number number) 
      { 
       if (number is Fraction) 
       { 
        Fraction fraction = (Fraction)number; 
        return new ComplexNumber((Fraction)(m_real/fraction), 
         (Fraction)(m_imaginary/fraction)); 
       } 
       ComplexNumber complexNumber = (ComplexNumber)number; 
       return new ComplexNumber((Fraction)((Fraction)(m_real * complexNumber.m_real + 
        m_imaginary * complexNumber.m_imaginary)/(Fraction)(complexNumber.m_real * 
        complexNumber.m_real + complexNumber.m_imaginary * complexNumber.m_imaginary)), 
        (Fraction)((Fraction)(m_imaginary * complexNumber.m_real - 
        m_real * complexNumber.m_imaginary)/(Fraction)(complexNumber.m_real 
        * complexNumber.m_real + complexNumber.m_imaginary * complexNumber.m_imaginary))); 
      } 
      public override string ToString() 
      { 
       StringBuilder output = new StringBuilder(); 
       if (m_imaginary.getNumerator() != 0) 
       { 
        m_imaginary.reduce(); 
        if (m_imaginary.getNumerator() > 0) 
        { 
         if (m_real.getNumerator() != 0) 
         { 
          output.Append(m_real.ToString()); 
          output.Append("+"); 
         } 
         if (m_imaginary.getNumerator() != 1) 
          output.Append(m_imaginary.getNumerator()); 
        } 
        else if (m_imaginary.getNumerator() < 0) 
        { 
         if (m_real.getNumerator() != 0) 
          output.Append(m_real.ToString()); 
         output.Append("-"); 
         if (m_imaginary.getNumerator() != -1) 
          output.Append(-m_imaginary.getNumerator()); 
        } 
        output.Append("i"); 
        if (m_imaginary.getDenominator()!=1) 
        { 
         output.Append("/"); 
         output.Append(m_imaginary.getDenominator()); 
        } 
       } 
       else if (m_real.getNumerator() != 0) 
        output.Append(m_real.ToString()); 
       else 
        return "0"; 
       return output.ToString(); 
      } 
      public override bool Equals(object obj) 
      { 
       if (obj is ComplexNumber) 
       { 
        ComplexNumber complexNumber = (ComplexNumber)obj; 
        return m_real.Equals(complexNumber.m_real) && 
         m_imaginary.Equals(complexNumber.m_imaginary); 
       } 
       return false; 
      } 
      public override int GetHashCode() 
      { 
       return m_real.GetHashCode() | m_imaginary.GetHashCode(); 
      } 
     } 

再次编辑:a link to a text file of the whole program,就此而言。

+0

发布您的ComplexNumber类 –

+2

heisenbug提出了一种竞争条件,或者说您的调试器正在评估具有副作用的表达式。你做*任何*异步,线程,后台任务等? – Amy

+0

@Amy如果我有任何这些东西,我已经设法使用它们而没有意识到它。有没有一种巧妙的方式将这些东西引入到一个程序中,例如,它不涉及显式使用async关键字或创建一个Thread对象?我没有创建的唯一命名空间是System,System.Collections.Generic和System.Text。 –

回答

0

其他人在其他地方提出这个问题与我为Fraction类定义的ToString()的重载具有调用reduce()的副作用有关,并且由于调试器按顺序使用了ToString()为了显示变量的值,调试器可能会在我的Fraction对象的内部中断执行。有几个原因可能会导致问题的原因,我认为这会导致调试行为异常,但不会影响运行,而不是相反,但我听从了他们的建议,并安排了在Fraction构造函数中发生的所有减少,并且这确实解决了问题。如果有人对此如何工作有更清楚的解释,我将不胜感激。

相关问题