我写了一个简短的函数来计算一个值的位数(整数部分)。
template <typename T>
static size_t digits(T num) {
auto is_fraction_of_one = [](T num) {
return (num > 0 && num < 1) || (num > -1 && num < 0);
};
if (num == 0 || is_fraction_of_one(num))
return 1;
return std::is_unsigned_v<T> ? \
static_cast<size_t>(std::log10(num)) + size_t(1) : \
static_cast<size_t>(std::log10(num < 0 ? -num : num)) + size_t(1);
}
如果0 <= abs(num) < 1
返回1,否则它将通过std::log10(num)+1
计算位数。
代码按原样工作,但是编译器(Windows VC ++)警告:
警告C4146:一元减运算符应用于无符号类型,结果 仍未签名
这很公平,因为它不认识到最后一行中的-num
部分仅在签名T
时执行。
如果我想重写代码以防止出现此警告,我该怎么办?
由于std::is_unsigned_v是constexpr
,我觉得我应该能够将代码分成两个单独的模板函数:一个用于签署T
时,另一个用于签署时。不。但是我不知道该怎么做。
我意识到我可以缩短代码,并通过将num
强制转换为double
来避免警告(因为std::log10
仍然会在没有模板arg的情况下执行此操作):
template <typename T>
static size_t digits(T num) {
double dnum = std::fabs(static_cast<double>(num));
if (dnum >= 0.0 && dnum < 10.0)
return 1;
return static_cast<size_t>(std::log10(dnum)) + size_t(1);
}
但是我要问的问题主要是出于我自己的学历。另外,我确实还有一些其他功能,它们可能会从该解决方案中获得更适当的收益(无论如何)。