首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在x86-64中实现rint()

在x86-64中实现rint()
EN

Stack Overflow用户
提问于 2014-02-06 19:35:02
回答 1查看 454关注 0票数 1

MSVC 2012没有rint()函数。对于32位,我使用以下代码:

代码语言:javascript
复制
double rint(double x) {
    __asm {
        fld x
        frndint
    }
}

这在x64中不起作用。有_mm_round_sd(),但它需要SSE4。获得相同行为的有效且最好是无分支的方法是什么?

EN

回答 1

Stack Overflow用户

发布于 2014-02-06 22:12:34

rint 64位模式

代码语言:javascript
复制
#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位模式

代码语言:javascript
复制
// 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位模式

代码语言:javascript
复制
// 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函数。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21601806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档