将常量值双精度映射到整数的现代方法是什么?
我希望这只作为标题包含。
我已经避免#define
并开始使用if
语句的嵌套。
我相信if
语句更快(我将它们列为优先级,并且其中有一些goto
)但下面的开关似乎更具可读性。
我看了下面的代码拆解,看起来很合理。
我不喜欢巨型开关。我认为可能有更好的现代方法(不会失去性能或需要链接)。
inline int InchtoGauge(double d)
{
switch (static_cast<int>(d * 10000))
{
case 2391: return 3;
case 2242: return 4;
case 2092: return 5;
case 1943: return 6;
case 1793: return 7;
case 1644: return 8;
case 1495: return 9;
case 1345: return 10;
case 1196: return 11;
case 1046: return 12;
case 897: return 13;
case 747: return 14;
case 673: return 15;
case 598: return 16;
case 538: return 17;
case 478: return 18;
case 418: return 19;
case 359: return 20;
case 329: return 21;
case 299: return 22;
case 269: return 23;
case 239: return 24;
case 209: return 25;
case 179: return 26;
case 164: return 27;
case 149: return 28;
case 135: return 29;
case 120: return 30;
case 105: return 31;
case 97: return 32;
case 90: return 33;
case 82: return 34;
case 75: return 35;
case 67: return 36;
default:return -1;
}
}
答案 0 :(得分:2)
执行某些内容的标题实现,认为是一个问题,这不是问题。
比较等式的小数浮点值,代码显示您认为没有问题,这是主要的问题。
函数名get_user_by('slug','john-doe');
表明命运多like的比较仅仅是一个简单函数的实现。你应该只计算那个功能。它看起来像这样(你可以只插入几个值):
顺便说一下,显然代码中的大量值是从5个直线段计算出来的。至少它看起来对我来说。这意味着您可以使用远远少于您的值来定义函数。
答案 1 :(得分:1)
无论您实际想如何使用数据,我认为最好先将其存储为一些简单,精确的形式:
static constexpr int GaugeToInchScale = 10000;
static constexpr std::array<int, 34> GaugeToInchScaledData = { 2391, 2242, ..., 67 };
static constexpr int GaugeToInchFirstGauge = 3;
然后,使用这些数据的任何函数都将根据常数来实现,无论哪种意义都是最自然的。
如果需要,可以从这些数据中合成其他表格 - 如果需要,甚至可以as compile time constants。
这是一个简单的编译时算法示例,它只生成一个if
语句的线性链,用于测试相等性。这个例子的目的不是制作一个有效的算法,而是为了演示如何编写这种类型的算法。
// searcher<N>::search(x) assumes `x` doesn't appear among the first `N` entries
template< int N >
struct searcher {
constexpr static int search(int x) {
if (x == GaugeToInchScaledData[N]) {
return N + GaugeToInchFirstGauge;
}
return searcher<N+1>::search(x);
}
};
template<>
struct searcher<GaugeToInchScaledData.size()>
{
constexpr static int search(int x) {
return -1;
}
};
int search(int n) { return searcher<0>::search(n); }
答案 2 :(得分:1)
我比较了switch方法,unorder_map和binary_search (我忽略了* 10000)
int InchtoGauge2(int d) {
const int lut[] = {
2391, 2242, 2092, 1943, 1793,
1644, 1495, 1345, 1196, 1046,...
};
const int N = sizeof(lut)/sizeof(lut[0]);
const int n = lower_bound(lut, lut+N, d, greater<int>()) - lut;
return (n==N || lut[n]!=d)? -1: 3+n;
}
int InchtoGauge3(int d)
{
unordered_map<int,int> m{
{2391, 3},
{2242, 4},
{2092, 5},...
};
auto p = m.find(d);
return p == m.end()? -1: p->second;
}
我已多次执行它们了。
所以只需使用开关/案例......
<强>被修改强>
我尝试拆分cpp文件(以防止一些优化) 并使对象静止。
差距仍然很大但变小了。
运行时间: