簡體   English   中英

使用浮點常量設置和檢查

[英]Setting and checking with a float constant

我知道這里有很多關於為什么浮動相等比較通常不是一個好主意的問題。 我了解浮點數表示問題、舍入問題、將浮點數無聲地提升為雙精度數、在位級別依賴算術的危險等。但在我看來,這應該沒問題,而且我發現的任何問題似乎都涵蓋了這一點:

static const float MARKER = -500.0f; // some value well outside the range of valid values
std::vector<float> some_floats = {MARKER, 0.5f, 100.0f, 9.5f, MARKER, 0.f};
for (size_t i = 0; i< some_floats.size(); ++i) {
    if (some_floats[i] == MARKER) {             
       std::cout << i << std::endl;
    } else {
       // do some math
    }
}

output 符合預期:

0
4

如果我啟用了-Wfloat-equal (在 gcc 中,但在其他編譯器中類似),它會將比較行標記為危險: comparing floating point with == or != is unsafe 這里幾乎所有的答案都說不要使用 == or,=, period 但我不明白為什么這是一個問題。 我只設置常量一次,然后在其他任何地方重復使用它,並且永遠不會對該常量進行任何操作(例如算術)。 我錯過了什么嗎? 0.0f怎么樣,即使沒有設置為常量?

只要您確信MARKER及其副本不會被算術函數或其他東西改變,進行簡單比較就沒有問題。
也許考慮不在全球范圍內使用-Wfloat-equal但在本地禁用警告:

    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wfloat-equal"
    /* your code */
    #pragma GCC diagnostic pop

或便攜式等同物: https://www.fluentcpp.com/2019/08/30/how-to-disable-a-warning-in-cpp/

您錯過了何時使用浮動的原因。 你用花車做數學。 只要你只比較浮點數就沒問題。 但是,一旦您對數字進行一些操作並在之后比較它們,它通常不會起作用(即使在某些情況下它可能起作用),因為浮點運算並不精確。 這就是人們說“不要比較浮點數”時的意思。

此外,許多編譯器都有用於指定浮點行為的標志。 例如,對於 MSVC,請查看此處 這使得更明顯的是,精確比較永遠不會是一個好主意。

如果你想像這樣標記浮點數,你當然可以這樣做,但是,為了安全起見,我建議使用std::numeric_limits<float>::min()作為標記值。 請確保不要以數學方式操縱這些值。 還要考慮到其他開發人員可能會將浮點數的存在視為可以有效操縱這些值的指示符,這並不好。 作為替代方案,您可以考慮 std::optional 來標記數字是否有效。

正如對static的評論一樣:我進一步建議放棄 static,因為確實沒有必要,而且性能這個詞突然出現在某處。 我會把它改成這樣:

const float MARKER = std::numeric_limits<float>::min();  // some value well outside the range of valid values
std::vector<float> some_floats = {MARKER, 0.5f, 100.0f, 9.5f, MARKER, 0.f};
for (size_t i = 0; i < some_floats.size(); ++i) {
    if (some_floats[i] == MARKER) {
        std::cout << i << std::endl;
    } else {
    // do some math
}

}

暫無
暫無

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

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