我写了一个类来表示方位(角度与航海主题,和一个具体的正常化范围)。在程序中,有必要对它们执行一些数学操作,因此我重载了+、-、*和/运算符(这是C++中的)。
我的问题是:什么样的运算符在数学上定义得很好?或者更具体地说,在下面的代码中,是否有任何我不应该定义的运算符,以及是否有任何未定义的运算符是我应该定义的?
constexpr inline Bearing operator+(Bearing lhs, Bearing rhs) noexcept
{
return Bearing::deg(lhs.getInDegrees() + rhs.getInDegrees());
}
constexpr inline Bearing operator-(Bearing lhs, Bearing rhs) noexcept
{
return Bearing::deg(lhs.getInDegrees() - rhs.getInDegrees());
}
template <
typename T,
typename = EnableIfNumeric<T>
> constexpr inline Bearing operator*(Bearing lhs, T rhs) noexcept
{
return Bearing::deg(lhs.getInDegrees() * static_cast<Bearing::ValueType>(rhs));
}
template <
typename T,
typename = EnableIfNumeric<T>
> constexpr inline Bearing operator*(T lhs, Bearing rhs) noexcept
{
return Bearing::deg(static_cast<Bearing::ValueType>(lhs) * rhs.getInDegrees());
}
template <
typename T,
typename = EnableIfNumeric<T>
> constexpr inline Bearing operator/(Bearing lhs, T rhs) noexcept
{
return Bearing::deg(lhs.getInDegrees() / static_cast<Bearing::ValueType>(rhs));
}
template <
typename T,
typename = EnableIfNumeric<T>
> constexpr inline Bearing operator/(T lhs, Bearing rhs) noexcept; // Intentionally not defined
constexpr inline Bearing::ValueType operator/(Bearing lhs, Bearing rhs) noexcept
{
return lhs.getInDegrees() / rhs.getInDegrees();
}
// Bearing has value semantics
constexpr inline Bearing operator+=(Bearing lhs, Bearing rhs) noexcept; // Intentionally not defined
constexpr inline Bearing operator-=(Bearing lhs, Bearing rhs) noexcept; // Intentionally not defined
constexpr inline Bearing operator*=(Bearing lhs, Bearing rhs) noexcept; // Intentionally not defined
constexpr inline Bearing operator/=(Bearing lhs, Bearing rhs) noexcept; // Intentionally not defined
constexpr inline bool operator==(Bearing lhs, Bearing rhs) noexcept
{
return lhs.getInDegrees() == rhs.getInDegrees();
}
constexpr inline bool operator!=(Bearing lhs, Bearing rhs) noexcept
{
return !(lhs == rhs);
}用词:
注意,所谓“正规化”,我指的是环绕角度,使它们始终在[0,360)或[-180,180]范围内,并且该操作仅在客户请求时执行,而不是在每次操作之后执行。
我认为这个问题很适合程序员,但是如果有几个人认为它更适合于代码评审,那么我会考虑把它移到那里。
发布于 2015-02-04 13:55:50
这取决于“数学上定义良好”的含义。您的所有函数都在有唯一定义的意义上得到了很好的定义。然而,乘法和除法是有问题的,因为它们不能保证
(b * n) * m == b * (n * m)nor
(b * n) / m == b * (n / m)其中b是轴承,n是数字值,这就是您可能期望的。例如,如果b = 45°和n = m = 8
(b * n) / m == 360° / 8 == 0° / 8 == 0°但b* (n / m) == 45°*1 == 45°
(或者使用乘法,设置m = 1/8,它显示的本质是相同的)。
所以,如果你想让这件事变得万无一失,我建议你用调用者给出的间隔(例如,0°到360°或乘法,或者设置为-180°到180°)添加一个从轴承到浮点的转换操作符。乘法和除法只能通过使用这个范围把一个方位转换成一个数字,然后应用这个运算,然后再转换回一个方位。这样就可以消除每一个歧义。
https://softwareengineering.stackexchange.com/questions/272084
复制相似问题