将整数限制在范围内[重复]
Posted
技术标签:
【中文标题】将整数限制在范围内[重复]【英文标题】:Limit integer to bounds [duplicate] 【发布时间】:2017-05-22 23:31:11 【问题描述】:我正在尝试确保 int x
大于或等于 0 但小于 1080(在这种情况下为屏幕尺寸)。
我想出了这个
int x = 123;
x = std::min(std::max(x, 0), 1080);
这看起来很难看。有没有更好的方法来实现这一点?
【问题讨论】:
对我来说看起来不错。写一个wapper函数...boost.org/doc/libs/1_54_0/libs/algorithm/doc/html/algorithm/… 明确执行if (x >= 0 && x < 1080) // your code here.
我会使用代码来确保范围,并将其包装在模板中,例如this。
【参考方案1】:
如果你生活在未来,你可以使用std::clamp
from C++17:
x = std::clamp(x, 0, 1080);
【讨论】:
未来的加一!从未来的标准中包含好的 sn-ps 并没有什么坏处。 好的,谢谢,这主要是我想要的。我会保留最小/最大组合,直到未来到来 @Eric:嗯??只需编写自己的包装器,然后在时机成熟时将其替换为夹子......【参考方案2】:简单的解决方案看起来也不错:
int x = 123;
if (x < 0)
x = 0;
if (x > 1080)
x = 1080;
或将所有内容包装在一个函数中:
template<typename T>
T between(const T x, const T min, const T max)
if (x < min)
return min;
if (x > max)
return max;
return x;
int x = between(123, 0, 1080);
【讨论】:
代码已修复,抱歉 写起来相当简单,读起来超级简单......当问题真的很简单时,不需要超级复杂的 C++17 东西。我的首选方式!【参考方案3】:使用无符号作为 x 的类型。这会自动将其限制为非负数。
那么你只剩下对 std::min 的调用了,这至少对我来说是可以接受的。
构建一个在构造上采用 int 并具有转换运算符到 int 的类也是可行的,但需要相当多的样板。
【讨论】:
这是个好主意,但不幸的是 x 是通过 API 回调获取的,因此我无法轻松更改类型。当然我可以将 int 转换为 unsigned int,但这也很丑 imo【参考方案4】:为什么不做这样的事情呢?
int x = 123; /* Or some arbitrary number */
bool bIsInRange = (x >= 0) && (x < 1080);
if(!bIsInRange)
std::cout << "Variable 'x' is not between 0 and 1080." << std::endl;
return 1;
// else, x is fine. Continue operations as normal.
【讨论】:
看起来超级难看。 @melpomene,然而,对于任何经验水平的任何人来说,它都是标准的、可读的和极易理解的。此外,以这种正常方式执行此操作不需要额外调用诸如min
、max
或clamp
之类的函数,这只会增加原本简单且基本上没有重量的任务的开销/费用。话虽如此,我同意这绝不是“美丽”。
我觉得它不可读。主要问题是bIsInRange
变量,它没有任何作用,而且名字很糟糕。至于开销,我希望编译器能够内联 min/max/clamp。 (如果我们谈论效率,cout << "..." << endl
构造可能比普通函数调用慢 100 倍。)以上是关于将整数限制在范围内[重复]的主要内容,如果未能解决你的问题,请参考以下文章