加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – cvRound()中的x64舍入不一致(_mm_cvtsd_si32)

发布时间:2020-12-16 10:35:24 所属栏目:百科 来源:网络整理
导读:在使用MSVC2013的x64 Windows上,我使用的是OpenCV的cvRound函数,目的是从x.5值向上舍入.我遇到了一个不一致的地方,cvRound(17.5f)返回18(好!),但cvRound(20.5f)返回20而不是21 因此简单地实现了cvRound,因此它似乎是_mm_cvtsd_si32()中的Microsoft不一致. i
在使用MSVC2013的x64 Windows上,我使用的是OpenCV的cvRound函数,目的是从x.5值向上舍入.我遇到了一个不一致的地方,cvRound(17.5f)返回18(好!),但cvRound(20.5f)返回20而不是21

因此简单地实现了cvRound,因此它似乎是_mm_cvtsd_si32()中的Microsoft不一致.

int  cvRound( double value )
{
    __m128d t = _mm_set_sd( value );
    return _mm_cvtsd_si32(t);
}

任何人都可以建议如何/为什么这样做?

FWIW,cvRound(20.5f 1e-3f)返回21.

解决方法

SSE指令的舍入行为可通过浮点环境(特别是MXCSR寄存器)进行配置.有 several IEEE rounding modes.默认的舍入模式是round-to-nearest,tie-to-even,所以如果该值恰好在两个可表示的值的中间,则结果四舍五入到最接近的偶数值.

请考虑以下测试程序,该程序演示了不同的舍入模式:

#include <fenv.h>
#include <immintrin.h>
#include <stdio.h>

int main()
{
    printf("Default:        %dn",_mm_cvtsd_si32(_mm_set_sd(20.5)));
    fesetround(FE_DOWNWARD);
    printf("FE_DOWNWARD:    %dn",_mm_cvtsd_si32(_mm_set_sd(20.5)));
    fesetround(FE_UPWARD);
    printf("FE_UPWARD:      %dn",_mm_cvtsd_si32(_mm_set_sd(20.5)));
    fesetround(FE_TONEAREST);
    printf("FE_TONEAREST:   %dn",_mm_cvtsd_si32(_mm_set_sd(20.5)));
    fesetround(FE_TOWARDZERO);
    printf("FE_TOWARDZERO:  %dn",_mm_cvtsd_si32(_mm_set_sd(20.5)));
}

输出:

Default:        20
FE_DOWNWARD:    20
FE_UPWARD:      21
FE_TONEAREST:   20
FE_TOWARDZERO:  20

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读