为什么我在这个表达式中的所有值都为零

Why am I getting zero for all values in this expression?

本文关键字:表达式 为什么      更新时间:2023-10-16

下面是一个程序片段,用于推断 2 行是否相交。 P and P2是标记 2 行之一的起点和终点的CPoint对象。

double m1,m2;  //slopes
double b1,b2;     //y-intercepts
double y,x;     //intersection point
m1=(max(P.y,P2.y) - min(P.y,P2.y)) /( max(P.x,P2.x) - min(P.x,P2.x) );

出于某种原因,我总是m1变得0.这是为什么呢?

如果您的CPoint类是具有整数坐标的点,则必须在此处进行一些转换才能获得所需的结果。请参阅以下问题演示。考虑两点P = (1, 4)P2 = (5, 3)

m1=( max(P.y,P2.y) - min(P.y,P2.y) ) / ( max(P.x,P2.x) - min(P.x,P2.x) );
     ^^^^^^^^^^^^^   ^^^^^^^^^^^^^       ^^^^^^^^^^^^^   ^^^^^^^^^^^^^
           4               3                    5               1
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                   1                                   4

但是,在整数除法中,1 / 40 ,但您希望结果0.25 。结果变量具有double类型这一事实不会更改表达式的值(和类型)。

为了解决这个问题,你必须在表达式的各个部分被看作是非整数之前,将它们转换为非整数。在您的情况下,这是除法的操作数,因此它将是一个浮点除法。(投射除法的结果也无济于事。

m1 = static_cast<double>( max(P.y,P2.y) - min(P.y,P2.y) )
   / static_cast<double>( max(P.x,P2.x) - min(P.x,P2.x) );

请注意,转换第二个操作数是可选的,因为double / int始终使用浮点除法。

另请注意,表达式将计算斜率的绝对值。您可能想要计算带符号斜率。


您可以在代码中改进一些内容(这不会解决上述问题): 不要减去差值最大值的最小值,只需取差值的绝对值:

m1 = static_cast<double>( abs(P.y - P2.y) )
   / static_cast<double>( abs(P.x - P2.x) );

由于在C++中,abs是一个模板函数(在 C 中它是一个宏,呃...),您还可以使用显式模板类型强制使用结果类型:

m1 = abs<double>(P.y - P2.y)
   / abs<double>(P.x - P2.x);

此外,由于计算两个给定点之间的斜率似乎是一个常用的函数,因此您可以在两个CPoint上将其实现为独立函数:

double absoluteSlope(const CPoint & p, const CPoint & q) {
    return abs<double>(p.y - q.y) / abs<double>(p.x - q.x);
}

更好的是,要使用C++模板,请在具有成员xy的泛型类上实现它:

template<class T>
double absoluteSlope(const T & p, const T & q) {
    return abs<double>(p.y - q.y) / abs<double>(p.x - q.x);
}

此解决方案现在适用于具有整数坐标的CPoint实例以及具有浮点/双精度坐标的(可能即将推出的)CPointF类。

如上所述,这将计算绝对斜率。要将其更改为数学上正确的(有符号)斜率,只需将abs替换为static_cast

template<class T>
double slope(const T & p, const T & q) {
    return static_cast<double>(p.y - q.y) / static_cast<double>(p.x - q.x);
}

分区 A/B 应为 A/(double)B。晶圆厂也代替腹肌。

相关文章: