2017-10-04 61 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構造函數中發生的所有減少,並且這確實解決了問題。如果有人對此如何工作有更清楚的解釋,我將不勝感激。

相關問題