2014-12-07 69 views
0

浮點我有這樣的結構:對於比較升序排序

typedef struct _Preset Preset; 
struct _Preset 
{ 
    gfloat freq; 
}; 

我希望能夠按升序排序。 我寫這個函數使用整數「字典順序」檢查是否兩個浮點數比較接近對方:

gint comp_func_sort_float(Preset *ps1, Preset *ps2) 
{ 
    gint freq1, freq2; 

    freq1 = *(int*)&ps1->freq; 
    freq2 = *(int*)&ps2->freq; 

    return (freq1 - freq2); 
} 

我想用有限的精度進行比較:

gint comp_func_sort_float(float A, float B) 
{ 
    int dif; 

    assert(sizeof(float) == sizeof(int)); 

    if (A == B) 
     return 0; 

    dif = abs(*(int*)&A - *(int*)&B); 

    if (dif <= 0.25f) 
     return 0; 

    return -1; 
} 

存在另一個這樣做的方法。

+2

鑄造一個指向'浮'指向'int'的指針,然後取消引用該指針不會很好。除非'int'和'glfloat'以相同的格式存儲,否則不會得到遠近接近實際值的值。事實上,你對這段代碼的看法是[* undefined behavior *](http://en.wikipedia.org/wiki/Undefined_behavior)。 – 2014-12-07 01:17:36

+0

「另一個」是錯誤的詞,因爲作爲比較函數,你沒有意義。線索是它永遠不會返回負數。 – Gene 2014-12-07 01:18:54

+0

@Gene:那麼,至少第二個「可選」方式稍好一些。 – usr2564301 2014-12-07 01:20:12

回答

0

即使您獲得了正確的大小和字節順序,2的補碼,IEEE binary32等,覆蓋int而不是float不會給出相同的數字順序。對float的位解釋更像符號量級,而不是2的補碼。

推薦:

gint comp_func_sort_float(float A, float B) 
    return (A > B) - (A < B); 
} 
0

您正在閱讀的float S作爲int S,所以你有效地比較了IEEE 754 符號,而不是浮點值。

由於您正在有效比較「整數」,因此dif測試完全沒用。首先,你的輸入被轉換成整數。接下來,您使用的是abs,即使輸入爲浮點型,也會返回一個整數。最後,dif本身也是一個整數,雖然與float值的比較是有效的,但在這一點上肯定不會做任何有用的事情。

我也想知道爲什麼你從使用comp_func_sort_float(Preset *ps1, Preset *ps2)中的指針切換到comp_func_sort_float(float A, float B)中的直接參數。我將假設指針符號是正確的,因爲它應該是qsort和等效函數。

此工作正常,處理定義爲「相等」和返回正確的整數的+/- 0.25的差(-1,0,1)所有的比較:

int comp_func_sort_float(const void *Aa, const void *Bb) 
{ 
    float A = *(float *)Aa, B = *(float *)Bb; 
    float dif; 

    dif = A - B; 

    if (dif <= -0.25f) 
     return -1; 
    if (dif >= 0.25f) 
     return 1; 

    return 0; 
}