簡體   English   中英

HSV轉換中的浮點錯誤

[英]Floating point error in HSV conversion

我有一個功能,用於將RGB色彩空間中的矢量轉換為HSV - 例程通過所有測試並在絕大多數時間內工作。 但是,崩潰報告表明它偶爾會失敗(0.0001%的呼叫或更少。)但是,由於此功能被調用太多,這占據了軟件總崩潰的很大一部分。

代碼的相關部分如下:

glm::vec4 RGBtoHSV(glm::vec4 rgb)
{
    vec4 hsv = vec4(0,0,0,rgb.w);

    float r = rgb.x;
    float g = rgb.y;
    float b = rgb.z;
    float M = std::max(std::max(r,g),b);
    float m = std::min(std::min(r,g),b);
    float c = M - m;

    //calc hue
    float hp = 0;
    if (c == 0)
        hp = 0;
    else if (M == r)
        hp = glm::mod(((g-b)/c), 6.0f);
    else if (M == g)
        hp = ((b-r)/c) + 2;
    else if (M == b)
        hp = ((r-g)/c) + 4;
    else
        EXPECT(false);
    float h = hp * 60;

    ...

glm :: vec4是對GLM庫的引用,但類型基本上只是這樣:

struct vec4 {
    union {
        struct { float x, y, z, w; }
        struct { float r, g, b, a; }
    }
}

失敗的行是EXPECT(false); - 這只是斷言我們總是達到其中一個上層案例,問題是如何控制到達那里?

假設這些是IEEE-754浮點數,那么與NaN相比可能會遇到問題。 如果您使用不同的浮點表示,那么我的答案的其余部分可能不相關。

聽起來有點奇怪,但與NaN 任何比較都會返回False。 所以,即使你試圖做NaN == Nan你也會得到假。 MSDN鏈接

如果您在代碼中引發斷言的部分測試NaN ,那么這可能就是問題所在。 您可以使用<cmath>isnan()來執行此操作,請參閱http://en.cppreference.com/w/cpp/numeric/math/isnan

我快速匯總了一些代碼來演示,如果您的系統發生同樣的情況,請告訴我:

#include <iostream>
#include <cmath>
int main(){
    float r = 0.0/0;
    std::cout << "r = " << r <<  std::endl;
    float g = 7.0;
    float b = 0.0;
    float M = std::max(std::max(r,g),b);
    float m = std::min(std::min(r,g),b);
    float c = M - m;

    //calc hue
    float hp = 0;
    if (c == 0)
        std::cout << "c == 0" << std::endl;
    else if (M == r)
        std::cout << "M == r" << std::endl;
    else if (M == g)
        std::cout << "M == g" << std::endl;
    else if (M == b)
        std::cout << "M == b" << std::endl;
    else
        std::cout << "oops" << std::endl;
        if(std::isnan(M))
            std::cout << "NaN encountered" << std::endl;

}

在我用gcc編譯的機器上,這給出了以下輸出:

r = -nan
oops
NaN encountered

所以似乎有可能在代碼中的其他地方有0.0/0

暫無
暫無

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

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