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

使用SSE在Delphi中进行舍入

发布时间:2020-12-15 09:35:04 所属栏目:大数据 来源:网络整理
导读:我编写了这个函数来将单例转换成整数: function Round(const Val: Single): Integer;begin asm cvtss2si eax,Val mov Result,eax end;end; 它有效,但我需要改变舍入模式.显然,根据this,我需要设置MXCSR寄存器. 我如何在Delphi中执行此操作? 我之所以这样做
我编写了这个函数来将单例转换成整数:

function Round(const Val: Single): Integer;
begin
  asm
    cvtss2si eax,Val
    mov Result,eax
  end;
end;

它有效,但我需要改变舍入模式.显然,根据this,我需要设置MXCSR寄存器.

我如何在Delphi中执行此操作?

我之所以这样做的原因是我需要“远离零”舍入(就像在C#中一样),即使通过SetRoundingMode也是如此.

解决方法

在现代Delphi上,要设置MXCSR,您可以从系统单元调用 SetMXCSR.要读取当前值,请使用 GetMXCSR.

请注意SetMXCSR,就像Set8087CW一样,不是线程安全的.尽管我努力说服Embarcadero改变这一点,但似乎这个特殊的设计缺陷将永远留在我们身边.

在旧版本的Delphi中,您使用LDMXCSR和STMXCSR操作码.您可以编写自己的版本,如下所示:

function GetMXCSR: LongWord;
asm
  PUSH    EAX
  STMXCSR [ESP].DWord
  POP     EAX
end;

procedure SetMXCSR(NewMXCSR: LongWord);
//thread-safe version that does not abuse the global variable DefaultMXCSR
var
  MXCSR: LongWord;
asm
  AND     EAX,$FFC0 // Remove flag bits
  MOV     MXCSR,EAX
  LDMXCSR MXCSR
end;

这些版本是线程安全的,我希望能够编译和处理旧的Delphi版本.

请注意,为您的功能使用Round这个名称可能会引起很多混乱.我会建议你不要这样做.

最后,我查看了英特尔文档,两个英特尔浮点单元(x87,SSE)都提供了IEEE754标准规定的舍入模式.他们是:

>舍入到最近(偶数)
>向下舍入(朝向-∞)
>向上舍入(朝向∞)
>向零舍入(截断)

因此,您无法获得所需的舍入模式.

(编辑:李大同)

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

    推荐文章
      热点阅读