问题描述
有没有夹实数比使用if语句或三元运营商更有效的方法?
我想无论是双打和一个32位固定点实现(16.16)做到这一点。我的不可以要求code,可以处理这两种情况;他们将在单独的函数来处理。
Is there a more efficient way to clamp real numbers than using if statements or ternary operators?I want to do this both for doubles and for a 32-bit fixpoint implementation (16.16). I'm not asking for code that can handle both cases; they will be handled in separate functions.
显然,我可以这样做:
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;
的不动点的版本将使用函数/宏进行比较。
The fixpoint version would use functions/macros for comparisons.
这是在code的性能关键部分做了,所以我在寻找一种高效的方式来做到这一点越好(我怀疑将涉及的位操作)
This is done in a performance-critical part of the code, so I'm looking for an as efficient way to do it as possible (which I suspect would involve bit-manipulation)
编辑:它必须是标准的/可移植的C,特定于平台的功能是任何兴趣不在这里。此外, MY_MIN
和 MY_MAX
是相同类型的价值我想钳位(在上面的例子中双打)。
It has to be standard/portable C, platform-specific functionality is not of any interest here. Also, MY_MIN
and MY_MAX
are the same type as the value I want clamped (doubles in the examples above).
推荐答案
有关的16.16再presentation,简单的三元不太可能做得更好速度明智的。
For the 16.16 representation, the simple ternary is unlikely to be bettered speed-wise.
和双打,因为你需要它的标准/便携式C,任何种类的位小提琴演奏会结束得很惨。
And for doubles, because you need it standard/portable C, bit-fiddling of any kind will end badly.
即使位小提琴是可能的(我怀疑),你会依靠双打的二进制重新presentation。这样(和它们的大小)是实现相关。
Even if a bit-fiddle was possible (which I doubt), you'd be relying on the binary representation of doubles. THIS (and their size) IS IMPLEMENTATION-DEPENDENT.
也许你能猜测这用的sizeof(双),然后比较反对共同的二进制重新presentations各种双重价值观的布局,但我认为你是在一个藏身不了了之。
Possibly you could "guess" this using sizeof(double) and then comparing the layout of various double values against their common binary representations, but I think you're on a hiding to nothing.
最好的规则是告诉编译器你想要什么(即三元),让它优化你。
The best rule is TELL THE COMPILER WHAT YOU WANT (ie ternary), and let it optimise for you.
编辑:低声下气的时间。我只是测试quinmars想法(如下图),和它的作品 - 如果你有IEEE-754浮点数。这给了下面的code约20%的速度提升。 IObviously不可移植的,但我觉得有可能会问你的编译器如果它使用IEEE754浮点格式与#IF标准的方式...?
Humble pie time. I just tested quinmars idea (below), and it works - if you have IEEE-754 floats. This gave a speedup of about 20% on the code below. IObviously non-portable, but I think there may be a standardised way of asking your compiler if it uses IEEE754 float formats with a #IF...?
double FMIN = 3.13;
double FMAX = 300.44;
double FVAL[10] = {-100, 0.23, 1.24, 3.00, 3.5, 30.5, 50 ,100.22 ,200.22, 30000};
uint64 Lfmin = *(uint64 *)&FMIN;
uint64 Lfmax = *(uint64 *)&FMAX;
DWORD start = GetTickCount();
for (int j=0; j<10000000; ++j)
{
uint64 * pfvalue = (uint64 *)&FVAL[0];
for (int i=0; i<10; ++i)
*pfvalue++ = (*pfvalue < Lfmin) ? Lfmin : (*pfvalue > Lfmax) ? Lfmax : *pfvalue;
}
volatile DWORD hacktime = GetTickCount() - start;
for (int j=0; j<10000000; ++j)
{
double * pfvalue = &FVAL[0];
for (int i=0; i<10; ++i)
*pfvalue++ = (*pfvalue < FMIN) ? FMIN : (*pfvalue > FMAX) ? FMAX : *pfvalue;
}
volatile DWORD normaltime = GetTickCount() - (start + hacktime);
这篇关于夹一个真正的最快方法(固定/浮点)值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!