簡體   English   中英

對於 c++ 中的浮點數,a = -a 和 *= -1 之間有區別嗎?

[英]Is there a difference between a = -a and a *= -1 for floats in c++?

對於帶符號的 int 和 float 和 double 等類型? 因為,如果我沒記錯的話(一個非常大的 if),這只是一個翻轉的問題,我想是否有一個明確的操作可以讓代碼運行得更快?

編輯:好的,僅針對浮點類型, int 部分是我忘記使用我的大腦,抱歉)

-aa * -1是不同的操作。 1 C++ 標准中的任何內容都沒有明確要求實現為它們產生不同的結果,因此編譯器可能會將它們視為相同。 C++ 標准中的任何內容都不需要實現來對它們進行相同的處理,因此編譯器可能會對它們進行不同的處理。

C++ 標准在指定浮點運算方面非常松懈。 C++ 實現可以將一元-視為數學運算,因此-a相當於0-a 另一方面,C++ 實現可以考慮一元-是 IEEE-754否定( x ) 操作,根據 IEEE 754-2008 5.5.1:

... negate ( x ) 將浮點操作數x以相同格式復制到目標,反轉符號位。 否定( x ) 與減法(0, x ) 不同...

差異包括:

  • 求反是位級運算; 它翻轉符號位,即使操作數是信號 NaN 也不會發出異常信號1 ,並且可能傳播非規范編碼(與十進制格式相關)。
  • 減法和乘法是數學運算; 它們將發出2 個異常情況的信號,並且不會傳播非規范結果。

因此,您可能會發現編譯器會為a = -a;生成 XOR 指令。 這只是翻轉符號位,但生成a *= -1; . 它應該為a *= -1; 僅當實現不支持浮點標志、陷阱、信號 NaN 或任何其他使否定和減法/乘法可區分的東西時。

Godbolt 顯示帶有默認選項的 x86-64 Clang 11.0.0使用xor表示-amulss表示a * -1 但是x86-64 GCC 10.2對兩者都使用xorps

腳注

1我在這里隔離了-*操作; 作業部分不感興趣。

2 “信號”在此處使用 IEEE-754 意義,表示已發生異常情況的指示。 這可能導致引發標志,並可能導致影響程序控制的陷阱。 它與 C++ 信號不同,盡管陷阱可能會導致 C++ 信號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM