2014-12-07 65 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; 
}