在编译时简化分数以避免除以零

时间:2016-04-27 09:21:21

标签: c++ numeric fractions

有没有办法在评估之前简化分数,以避免被零除?

示例:

double x1 = 2;
double x2 = 2;
double x3 = 2;

double r1 = (x1-x2)/(x1-x2-x3);
cout << r1 << endl;
x3 = 0;
r1 = (x1-x2)/(x1-x2-x3);
cout << r1 << endl;

将返回:

-0
-nan

是否有可能使编译器在编译时简化第二个表达式以避免除零?特别是,如果x3等于0,我希望(x1-x2)/(x1-x2-x3)简化为1。

在我的代码中,因素x1x2x3被函数替换。

3 个答案:

答案 0 :(得分:1)

我已在评论中说明了以下内容(可能听起来有点粗鲁,但那只是因为我认为澄清这种误解非常重要):你不能通过简单地重新排列分数或取消来避免被零除。要了解原因,请考虑以下示例:

 x/y

这与

不同
 (0*x) / (0*y)

因为这会大大改变分数的值。一般来说

 x/y = (a*x) / (a*y)

为真,仅当 a 不为0 时。另一种看待这种情况的方法是考虑方程和可能的变换。考虑

a = b

这绝对不是

0*a = 0*b

但是

(a = b)  is equivalent to (a*x = b*x) 

仅在x不为0时才成立。

如果你想避免除零,唯一的方法是检查除数是否为0并以某种方式处理这种情况。你不能通过取消0来避免除零,因为这会改变分数的值。

答案 1 :(得分:0)

没有。特别是,如果通过函数调用获得x1,x2,x3的值,编译器如何知道x3为零,因此表达式减少为(x1-x2)/(x1-x2)?

但是,您可以在代码中明确地进行必要的测试,以检查在进行除法之前是否有办法简化表达式。

答案 2 :(得分:0)

正如他的回答中提到的那样,为什么不实施代码检查呢?它将是一个简单的if语句,并与运行时定义的变量兼容。

太糟糕了我还没有发表评论,因为在你的问题下有一个关于除零的讨论是有趣且主要是错误的。当然,将0/0设置为1是有意义的。更重要的是,您为x3显示的表达式的极限 - &gt; x1 - x2是1(或-1,取决于你来自哪里)。这意味着在特殊情况下,其中许多是实际用例,您可能希望将此特定n / A设置为1,以便计算可以继续进行而不会抱怨不重要(在某些情况下,非物理)无穷大。我显然是让你在数学上(或者至少在物理上)找到这个限制的正确用途,因为你并没有告诉我们你想要做什么。