数字的加法逆:从零减去或乘以 -1

Additive inverse of a number: subtraction from zero or multiplication by −1

取负数时哪种方法更快:-1*a0-a?其中 a 是双精度数。

两者都很糟糕,只需用 XOR 或专用的 FP 取反指令翻转符号位即可。

IEEE-754 浮点数使用 sign/magnitude 表示,因此 -xx 仅相差 1 位:sign-bit。 (例如,在带有 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,或者生成 a 最初使用 FNMSUB 而不是 FMADD 来取反来优化取反FMA 的一部分。


但是如果您必须在实际的 FP 乘法指令或 FP 加法指令之间进行选择,通常减法的延迟至少与乘法一样好。

Intel Haswell 和 Broadwell 的倍增吞吐量是增加吞吐量的两倍(运行 在 FMA 单元上具有更差或相同的延迟添加),但大多数微体系结构(包括现代 x86 Ryzen 和 Skylake)具有平衡的 FP添加与乘法吞吐量。

一般来说,对于非 x86 架构,加法至少和乘法一样便宜。但同样,大多数 ISA 都会有一些特殊的否定方式,例如 x86 的 SSE1 xorps 或旧版 x87 fchs (CHange Sign).

无条件清除符号位的布尔 AND 或 ANDN(或内置 "mask" 的专用指令)作为绝对值也很有用。