数字的加法逆:从零减去或乘以 -1
Posted
技术标签:
【中文标题】数字的加法逆:从零减去或乘以 -1【英文标题】:Additive inverse of a number: subtraction from zero or multiplication by −1 【发布时间】:2019-07-19 00:42:04 【问题描述】:对数字求反时哪种方法更快:-1*a
或 0-a
?其中a
是双精度。
【问题讨论】:
【参考方案1】:两者都很糟糕,只需使用 XOR 或专用的 FP 否定指令翻转符号位。
IEEE-754 浮点使用符号/幅度表示,因此 -x
与 x
仅相差 1 位:符号位。 (例如,在带有 SSE 的 x86 上,使用 xorps
How to negate (change sign) of the floating point elements in a __m128 type variable?)。这会将 NaN 翻转为 -NaN,反之亦然,而不会更改有效负载。
在 C 中,将其写为 -a
,然后看看你的编译器做了什么。
更好的是,您通常可以通过稍后执行减法而不是加法,或者使用 FMSUB 或 FNMADD 而不是 FMADD,或者最初使用 FNMSUB 而不是 FMADD 生成 a
来优化否定,以作为 FMA 的一部分进行否定.
但如果您必须在实际的 FP 乘法或 FP 加法指令之间进行选择,通常减法的延迟至少与乘法一样好。
英特尔 Haswell 和 Broadwell 的乘法吞吐量是加法吞吐量的两倍(在 FMA 单元上运行,加法延迟更差或相等),但大多数微架构(包括现代 x86 Ryzen 和 Skylake)都具有平衡的 FP 加法和乘法吞吐量。
一般来说,对于非 x86 架构,加法至少与乘法一样便宜。但同样,大多数 ISA 都会有一些特殊的否定方式,例如 x86 的 SSE1 xorps
或旧版 x87 fchs
(CHange Sign)。
用于无条件清除符号位的布尔 AND 或 ANDN(或内置“掩码”的专用指令)也可用作绝对值。
【讨论】:
以上是关于数字的加法逆:从零减去或乘以 -1的主要内容,如果未能解决你的问题,请参考以下文章