有没有办法用 xor 翻转 32 位浮点数的符号位?

Posted

技术标签:

【中文标题】有没有办法用 xor 翻转 32 位浮点数的符号位?【英文标题】:Is there a way to flip the sign bit of 32 bit float with xor? 【发布时间】:2019-07-11 15:37:54 【问题描述】:

我正在尝试翻转 xmm0 中最低有效浮点数的符号位。我试图将 -0 转换为另一个 xmm 寄存器并与 xmm0 进行异或。不幸的是,尽管我的浮动值消失了,但我已经实现了翻转标志。有没有办法在 asm 中使用xorps 来翻转符号位?我还在*** 上看到了一些帖子,但确实是这样做的,但是在 c 中。

# xmm0 contains 4 floats
# goal is to flip the sign of the least significant one
mov eax, -0
cvtsi2ss xmm1, eax
xorps    xmm0, xmm1

【问题讨论】:

mov eax, 0x80000000; movd xmm1, eax; xorps xmm0, xmm1 @Jester 非常感谢!那很快。我尝试过类似的方法,但并没有像我预期的那样成功。很遗憾,我无法接受您的解决方案。 仅供参考:-0 和 0 是相同的 2 的补码整数。 -0.0 和 0.0 是不同的浮点数。所以mov eax, -0 等价于mov eax, 0 @Jester 或者将0x80000000 放在内存中并用内存操作数引用它。 @Jester:如果你要即时生成它,我倾向于选择pcmpeqd xmm1,xmm1 / pslld xmm1, 31,除非你特别想不修改高元素。跨度> 【参考方案1】:

要翻转 xmm0 内最不重要的浮点数的符号位,解决方案类似于 Jester 在我的问题的评论部分中发布的内容:

mov eax, 0x80000000
movd xmm1, eax
xorps xmm0, xmm1

(感谢 Jester 和所有帮助过我的人。我只是想将此主题标记为已完成)

【讨论】:

如果您要避免从内存中加载常量,pcmpeqd xmm1,xmm1 / pslld xmm1, 31 与实现set1(-0.0) 向量的效率差不多。 (What are the best instruction sequences to generate vector constants on the fly?)。不过,这两种方式都是 9 个字节的代码,在 xorps 之前。唯一的区别是 uops 可以在哪些后端端口上运行。 movd 仅限于 Intel 上的一个端口(端口 5),pcmpeqdpslld 在大多数 CPU 上都可以在至少 2 个端口上运行。所以最好的选择取决于周围的代码。 movd 延迟概率。无关紧要。

以上是关于有没有办法用 xor 翻转 32 位浮点数的符号位?的主要内容,如果未能解决你的问题,请参考以下文章

浮点数的十六进制表示

将一个 32 位浮点数转换为两个 16 位 uint 数,然后再次转换回该 32 位浮点数

比较一个 32 位浮点数和一个 32 位整数而不强制转换为双精度,当任何一个值都可能太大而无法完全适合另一种类型时

c# 默认赋值

SSE 内在函数:将 32 位浮点数转换为 UNSIGNED 8 位整数

用脚编码音频:将 32 位浮点数转换为 mp3