为什么我在这个表达式中的所有值都为零
Why am I getting zero for all values in this expression?
下面是一个程序片段,用于推断 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 / 4
是0
,但您希望结果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++模板,请在具有成员x
和y
的泛型类上实现它:
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。晶圆厂也代替腹肌。
- 为什么constexpr的性能比正常表达式差
- 编译 llvm 3.1 时,为什么会出现错误:在">"标记之前预期主表达式
- 为什么在 while 循环中返回表达式不起作用
- 为什么C++正则表达式这么慢?
- 为什么不能用常量表达式声明数组?
- 为什么'typeid(x) == typeid(y)'的计算结果为 true,其中 'x' 和 'y' 分别是 T 和 T& 类型的 id-表达式?
- 为什么这个正则表达式C++在括号表达式中抛出无效范围异常?
- 为什么这个复合语句作为用大括号和括号括起来的语句序列似乎不是有效的语句表达式
- 为什么新表达式可以正确生成指针类型,即使它应该返回 void*?
- 为什么 Boost:正则表达式没有按预期找到所有结果?
- 为什么带有指针子对象的文字类类型的 constexpr 表达式不能是非类型模板参数
- 为什么'class'和'main'中的相等表达式表现不同?
- 在C++ Lambda 表达式中,为什么人们更喜欢按值捕获而不是作为参数传递?
- 为什么我的 SFINAE 表达式不再适用于 GCC 8.2?
- 针对 std::function 的 lambda 表达式和模板推导:为什么会这样?
- 为什么在template函数广播中把两个extensor表达式加在一起不正确
- 为什么C++中的表达式类型在不同版本之间会发生变化
- 为什么这个涉及重载运算符和隐式转换的C++表达式是不明确的
- 不同的结果在C、C++和Java中得到相同的表达式.为什么
- 没有从值到值的已知表达式&...为什么?