C++ 现代C++;将常数双精度映射为整数的方法
什么是将常量值加倍映射为整数的现代方法 我想这作为一个标题只包括 我避免了C++ 现代C++;将常数双精度映射为整数的方法,c++,c++11,dictionary,C++,C++11,Dictionary,什么是将常量值加倍映射为整数的现代方法 我想这作为一个标题只包括 我避免了#define,而是从一堆if语句开始 我相信if语句速度更快(我对它们进行了优先级排序,并在其中添加了一些gotos),但下面的切换看起来更具可读性 我看了下面代码的分解,这似乎是合理的 我不喜欢这个巨大的开关。我认为可能有一种更好的现代方法(不损失性能或需要链接) inline int InchtoGauge(双d) { 开关(静态_型(d*10000)) { 判例2391:申报表3; 案例2242:返回4; 案例20
#define
,而是从一堆if
语句开始
我相信if
语句速度更快(我对它们进行了优先级排序,并在其中添加了一些goto
s),但下面的切换看起来更具可读性
我看了下面代码的分解,这似乎是合理的
我不喜欢这个巨大的开关。我认为可能有一种更好的现代方法(不损失性能或需要链接)
inline int InchtoGauge(双d)
{
开关(静态_型(d*10000))
{
判例2391:申报表3;
案例2242:返回4;
案例2092:返回5;
案例1943:返回6;
案例1793:返回7;
案例1644:返回8;
案例1495:返回9;
案例1345:返回10;
案例1196:申报表11;
案例1046:返回12;
判例897:返回13;
判例747:返回14;
案例673:返回15;
案例598:返回16;
案例538:返回17;
判例478:申报表18;
案例418:返回19;
案例359:返回20;
案例329:返回21;
判例299:返回22;
判例269:申报表23;
案例239:返回24;
案例209:返回25;
案例179:返回26;
案例164:返回27;
案例149:返回28;
案例135:返回29;
案例120:返回30;
案例105:返回31;
案例97:返回32;
案例90:返回33;
案例82:返回34;
案例75:返回35;
案例67:返回36;
默认值:return-1;
}
}
对您认为有问题的内容执行仅标题的实现是没有问题的
这里的主要问题是比较分数浮点值是否相等(代码显示您认为没有问题)
函数名InchtoGauge
表明,命运多舛的比较只是一个简单函数的实现。你应该只计算这个函数。它看起来是这样的(您可以只对几个值进行插值):
顺便说一下,代码中的大量值显然是从5条直线段计算出来的。至少在我看来是这样的。这意味着您可以使用比现有值少得多的值来定义函数。对您认为有问题的内容执行仅标题的实现是没有问题的 这里的主要问题是比较分数浮点值是否相等(代码显示您认为没有问题) 函数名
InchtoGauge
表明,命运多舛的比较只是一个简单函数的实现。你应该只计算这个函数。它看起来是这样的(您可以只对几个值进行插值):
顺便说一下,代码中的大量值显然是从5条直线段计算出来的。至少在我看来是这样的。这意味着您可以使用比现有值少得多的值来定义函数。无论您实际希望如何使用数据,我认为最好先以某种简单、准确的形式存储数据:
static constexpr int GaugeToInchScale = 10000;
static constexpr std::array<int, 34> GaugeToInchScaledData = { 2391, 2242, ..., 67 };
static constexpr int GaugeToInchFirstGauge = 3;
无论您实际希望如何使用数据,我认为最好先以简单、准确的形式存储数据:
static constexpr int GaugeToInchScale = 10000;
static constexpr std::array<int, 34> GaugeToInchScaledData = { 2391, 2242, ..., 67 };
static constexpr int GaugeToInchFirstGauge = 3;
我比较了切换法、无序映射法和二进制搜索法 (我忽略了*10000)
intinchtogauge2(intd){
常量整数lut[]={
2391, 2242, 2092, 1943, 1793,
1644, 1495, 1345, 1196, 1046,...
};
常数int N=sizeof(lut)/sizeof(lut[0]);
const int n=下限(lut,lut+n,d,greater())-lut;
返回(n==n | | lut[n]!=d)?-1:3+n;
}
int InchtoGauge3(int d)
{
无序映射{
{2391, 3},
{2242, 4},
{2092, 5},...
};
自动p=m.find(d);
返回p==m.end()?-1:p->second;
}
我已经处决他们好几次了
- 开关/外壳228us
- 二进制搜索12913us
- 无序地图1307857us
- 开关/外壳x
- 二进制搜索15x
- 无序地图25x
intinchtogauge2(intd){
常量整数lut[]={
2391, 2242, 2092, 1943, 1793,
1644, 1495, 1345, 1196, 1046,...
};
常数int N=sizeof(lut)/sizeof(lut[0]);
const int n=下限(lut,lut+n,d,greater())-lut;
返回(n==n | | lut[n]!=d)?-1:3+n;
}
int InchtoGauge3(int d)
{
无序映射{
{2391, 3},
{2242, 4},
{2092, 5},...
};
自动p=m.find(d);
返回p==m.end()?-1:p->second;
}
我已经处决他们好几次了
- 开关/外壳228us
- 二进制搜索12913us
- 无序地图1307857us
- 开关/外壳x
- 二进制搜索15x
- 无序地图25x
std::lower_bound
)??关联数组、std::unordered_map或类似搜索。如果没有太多,我相信映射将是唯一的,没有冲突,它将执行得非常好。总比一个巨大的开关好。对于一个值数组,我建议使用数组。这里的主要问题是浮点值很少在相等时匹配。是否确实希望InchtoGauge(0.1)
返回-1
?将映射存储为
// 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); }
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;
}