我写了一个简单的程序来解决数学问题:
A^2+B^2 = 12
A*B = 9
(A+B)^2 = y
我的程序循环遍历从0.000000001
开始的每个数字,并检查第一个等式是否为真(第二个总是为真,因为我总是分配双B = 9 / A
)。
然后它写入结果并暂停。自从做了很多数学运算以来,这是永远的运行,我想知道我是否犯了任何错误,所以我可以解决它们?这是我的代码:
namespace AnnoyingMath1
{
class Program
{
static void Main(string[] args)
{
for (double a = 0.00000001; a < 9; a += 0.00000001) {
double b = 9 / a;
if (Math.Pow(a, 2) + Math.Pow(b, 2) == 12)
{
if (a * b == 9) // always true because b = 9 / a
{
Console.WriteLine("SUCCESS! a = " + a.ToString() + ", b = " + b.ToString() + ", y = (a+b)^2 = " + (Math.Pow(a + b, 2)).ToString() );
Console.ReadLine();
}
}
else {
Console.WriteLine("fail1 " + a.ToString() + " , " + b.ToString());
}
}
}
}
}
答案 0 :(得分:4)
是。确实如此。
语句如:
if (a * b == 9) // always true because b = 9 / a WRONG, because you are dealing with floating point
不正确。
永远不要直接比较浮点值。改为使用delta:
epsilon = 0.000001
if (Abs(a*b - 9) <= epsilon )
StackOverflow上有许多类似的问题。
请阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic
答案 1 :(得分:2)
你可能想要检查“足够接近”的答案,因为不能保证你会得到一个很好的整数。因此,检查(VAL)&gt;而不是检查(VAL)== 12。 11.9M&amp;&amp; &LT; 12.1M。另外,为什么不尝试某种收敛方法而不是循环遍历每个数字呢?
答案 2 :(得分:2)
既然你提到不能手工解决这个问题......
y = (a+b)^2
= a^2 + 2ab + b^2
= (a^2 + b^2) + 2 * ab
= 12 + 2 * 9
= 30
对代数问题蛮力绝不是正确的方法。
(当我意识到SO不是数学家庭作业帮助的地方时,我会在评论中加上这个,但格式化都很糟糕。)
答案 3 :(得分:1)
我不认为你会找到使用这种算法的答案,即使你在比较时使用delta。 Real Numbers内的方程式没有结果:
A + B = 9
A^2 + B^2 = 12
B = 9 / A
A^2 + (9 / A)^2 = 12
经过一些变换后,T = A ^ 2:
T^2 - 12T + 81 = 0
Delta = 144 - 4 * 81 < 0
您可以进一步进入complex numbers以使用虚构单位找到结果。