对于c++中的浮点运算,a=-a和a*=-1之间有区别吗



对于带符号的int、float和double等类型?因为,如果我没记错的话(一个很大的if(,这只是一个翻转的问题,我想是否有一个显式操作可以让代码运行得更快?

编辑:好吧,只是对于浮点类型,int部分是我忘记用脑子了,对不起(

-aa * -1是不同的操作1C++标准中没有任何东西公开要求实现为它们产生不同的结果,因此编译器可能会将它们视为相同。C++标准中没有任何东西要求实现对它们进行相同的处理,因此编译器可能会对它们进行不同的处理。

C++标准在指定浮点运算方面非常宽松。C++实现可以将一元-视为数学运算,从而使-a等价于0-a。另一方面,C++实现可以将一元-视为IEEE-754否定(x(操作,根据IEEE 754-2008 5.5.1:

取反(x(以相同格式将浮点操作数x复制到目标,反转符号位求反(x(与相减

差异包括:

  • 取反是一种位级运算;它翻转符号位,即使操作数是信令NaN,也不向1发送异常信号,并且可能传播非规范编码(与十进制格式相关(
  • 减法和乘法是数学运算;它们将发出2异常条件的信号,并且不传播非规范结果

因此,您可能会发现编译器为a = -a;生成XOR指令,该指令仅翻转符号位,但为a *= -1;生成乘法指令。只有当实现不支持浮点标志、陷阱、信号NaN或任何其他使否定和减法/乘法可区分的东西时,它才应该为a *= -1;生成XOR指令。

Godbolt显示,带有默认选项的x86-64 Clang 11.0.0对-a使用xor,对a * -1使用mulss。但是x86-64 GCC 10.2同时使用xorps

脚注

1我在这里隔离了CCD_ 15和CCD_;分配部分不感兴趣。

2此处使用IEEE-754意义上的"信号",表示出现异常情况。这可能导致一个标志被提升,并可能导致影响程序控制的陷阱。它与C++信号不同,尽管陷阱可能导致C++信号。

最新更新