我正在编写一个程序,该程序的行为被设计为来自用户的单个文本输入的功能,而不是其他任何东西。没有使用系统时钟,没有引用外部文件,没有多线程。然而,当我运行程序时,程序执行时的控制流程与调试时不同,我认为在这种情况下应该是不可能的。运行和调试之间的不同控制流程
它不会自行编译,但这里是工作不正常功能:
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,就此而言。
发布您的ComplexNumber类 –
heisenbug提出了一种竞争条件,或者说您的调试器正在评估具有副作用的表达式。你做*任何*异步,线程,后台任务等? – Amy
@Amy如果我有任何这些东西,我已经设法使用它们而没有意识到它。有没有一种巧妙的方式将这些东西引入到一个程序中,例如,它不涉及显式使用async关键字或创建一个Thread对象?我没有创建的唯一命名空间是System,System.Collections.Generic和System.Text。 –