有没有办法用 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),pcmpeqd
和 pslld
在大多数 CPU 上都可以在至少 2 个端口上运行。所以最好的选择取决于周围的代码。 movd 延迟概率。无关紧要。以上是关于有没有办法用 xor 翻转 32 位浮点数的符号位?的主要内容,如果未能解决你的问题,请参考以下文章
将一个 32 位浮点数转换为两个 16 位 uint 数,然后再次转换回该 32 位浮点数
比较一个 32 位浮点数和一个 32 位整数而不强制转换为双精度,当任何一个值都可能太大而无法完全适合另一种类型时