MSVC 2012没有rint()函数。对于32位,我使用以下代码:
double rint(double x) {
__asm {
fld x
frndint
}
}这在x64中不起作用。有_mm_round_sd(),但它需要SSE4。获得相同行为的有效且最好是无分支的方法是什么?
发布于 2014-02-06 22:12:34
rint 64位模式
#include <emmintrin.h>
static inline double rint (double const x) {
return (double)_mm_cvtsd_si32(_mm_load_sd(&x));
}有关lrint,请参阅Agner Fog的Optimizing C++ manual
32位模式
// Example 14.19
static inline int lrint (double const x) { // Round to nearest integer
int n;
#if defined(__unix__) || defined(__GNUC__)
// 32-bit Linux, Gnu/AT&T syntax:
__asm ("fldl %1 \n fistpl %0 " : "=m"(n) : "m"(x) : "memory" );
#else
// 32-bit Windows, Intel/MASM syntax:
__asm fld qword ptr x;
__asm fistp dword ptr n;
#endif
return n;
}64位模式
// Example 14.21. // Only for SSE2 or x64
#include <emmintrin.h>
static inline int lrint (double const x) {
return _mm_cvtsd_si32(_mm_load_sd(&x));
}编辑:我刚刚意识到这个方法会将值限制为+/- 2^31。如果你想要一个使用SSE2的更大范围的版本,这很复杂(但使用SSE4.1很容易)。有关示例,请参见文件vectorf128.h中Agner Fog的Vector类中的round函数。
https://stackoverflow.com/questions/21601806
复制相似问题