是否有比使用 if 语句或三元运算符更有效的方法来限制实数? 我想对 double 和 32 位定点实现 (16.16) 都执行此操作。我不要求可以处理这两种情况的代码;它们将在单独的函数中处理。
显然,我可以做这样的事情:
double clampedA;
double a = calculate();
clampedA = a > MY_MAX ? MY_MAX : a;
clampedA = a < MY_MIN ? MY_MIN : a;
或
double a = calculate();
double clampedA = a;
if(clampedA > MY_MAX)
clampedA = MY_MAX;
else if(clampedA < MY_MIN)
clampedA = MY_MIN;
定点版本将使用函数/宏进行比较。
这是在代码的性能关键部分完成的,因此我正在寻找一种尽可能有效的方法来完成它(我怀疑这会涉及位操作)
编辑:它必须是标准/可移植的 C,平台特定的功能在这里没有任何意义。此外,MY_MIN
和 MY_MAX
与我想要钳位的值的类型相同(上面示例中的 double )。
最佳答案
GCC 和 clang 都为以下简单、直接、可移植的代码生成漂亮的程序集:
double clamp(double d, double min, double max) {
const double t = d < min ? min : d;
return t > max ? max : t;
}
> gcc -O3 -march=native -Wall -Wextra -Wc++-compat -S -fverbose-asm lamp_ternary_operator.c
GCC 生成的程序集:
maxsd %xmm0, %xmm1 # d, min
movapd %xmm2, %xmm0 # max, max
minsd %xmm1, %xmm0 # min, max
ret
> clang -O3 -march=native -Wall -Wextra -Wc++-compat -S -fverbose-asm lamp_ternary_operator.c
Clang 生成的程序集:
maxsd %xmm0, %xmm1
minsd %xmm1, %xmm2
movaps %xmm2, %xmm0
ret
三个指令(不包括ret),没有分支。非常好。
这是在配备 Core i3 M 350 的 Ubuntu 13.04 上使用 GCC 4.7 和 clang 3.2 进行测试的。 附带说明一下,调用 std::min 和 std::max 的简单 C++ 代码生成了相同的程序集。
这是针对 double 的。对于 int,GCC 和 clang 都会生成具有 5 个指令(不包括 ret)并且没有分支的汇编。也很优秀。
我目前不使用定点,所以我不会对定点发表意见。
关于c - 限制真实(固定/浮点)值的最快方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23032492/