我有一个用于定点算术的类,下面是重要部分:
template <typename I, I S>
struct fixed
{
I value;
fixed(I i) : value(i * S) {}
template <typename J, J T> fixed(const fixed<J, T> &fx)
{
if (S % T == 0)
value = fx.value * (S / T);
else if (T % S == 0)
value = fx.value / (T / S);
else
value = S * fx.value / T;
}
static_assert(S >= 1, "Fixed-point scales must be at least 1.");
};
在GCC 4.4.5上,以下代码行:
fixed<int, 8> f = fixed<int, 2>(1);
生成错误:
fixed.hpp: In constructor ‘fixed<I, S>::fixed(const fixed<J, T>&) [with J = int, J T = 2, I = int, I S = 8]’:
fixed.hpp:81: error: division by zero
当代码中存在常量零除法时——T/S或S/T之一必须为零才能使规模不相等——如果S%T == 0(且S不为0),则S/T不为零。 GCC似乎只做了足够的优化,以确定我的分支中有一个保证会除以零,但没有足够的优化来确定保证不运行的分支。
我可以在文件中加入#pragma GCC diagnostic ignored "-Wdiv-by-zero"
,但这可能掩盖了真正的警告。
如何处理这种情况?(或者我的分析完全错误,我确实有一个真正的运行时除以零?)
T % S == 0
,那么fx.value / (T / S);
不就等同于S * fx.value / T
吗? - Jonas Bötel