比较其位表示中的浮点数

时间:2010-04-06 03:02:58

标签: c++ objective-c c floating-point

假设我想要一个需要两个浮点数(xy)的函数,我想比较它们不使用float表示,而是将它们按位表示为32-位unsigned int。也就是说,像-495.5这样的数字将位代表0b110000111110010111000000000000000xC3E5C000作为float,我有一个unsigned int具有相同的位表示(对应于小数值3286614016,我不在乎)。有没有简单的方法让我只使用各自<=对应文件中包含的信息对这些花车执行unsigned int等操作?

4 个答案:

答案 0 :(得分:4)

除非您确保所有原始值均为正数,否则您必须进行签名比较。必须使用与原始浮点类型大小相同的整数类型。每个芯片可能具有不同的内部格式,因此将不同芯片的值作为整数进行比较最有可能产生误导性结果。

大多数浮动格式如下所示:sxxxmmmm

s是一个符号位 xxx是指数
mmmm是尾数

表示的值将类似于:1mmm << (xxx-k)

1mmm因为除非值为零,否则隐含前导1位。

如果xxx < k那么它将是一个正确的转变。 k接近但不等于xxx可表达的最大值的一半。它根据尾数的大小进行调整。

尽管如此,忽略NaN,将浮点值作为相同大小的有符号整数进行比较将产生有意义的结果。它们的设计方式使得浮点比较不会比整数比较更昂贵。有编译器优化来关闭NaN检查,以便比较是直接整数比较,如果芯片的浮点格式支持它。

作为整数,NaN大于无穷大大于有限值。如果您尝试无符号比较,则所有负值都将大于正值,就像转换为无符号的有符号整数一样。

答案 1 :(得分:3)

总之,没有。 IEEE 754可能允许这样的某些类型的黑客,但它们不能一直工作并处理所有情况,并且某些平台不使用该浮点标准(例如x87内部具有80位精度的双打)。

如果你出于性能原因这样做我建议你强烈重新考虑 - 如果使用整数比较更快,编译器可能会为你做,如果不是,你需要支付浮点数转换为int多次,当可以在不将寄存器移出寄存器的情况下进行简单比较时。

答案 2 :(得分:3)

如果你真的真的不关心转换的收益率,那就不难了。但结果是非常不便携的,你几乎肯定不会得到一个完全类似你通过直接比较浮点数得到的排序。

typedef unsigned int TypeWithSameSizeAsFloat; //Fix this for your platform

bool compare1(float one, float two)
    union Convert {
        float f;
        TypeWithSameSizeAsFloat i;
    }
    Convert lhs, rhs;
    lhs.f = one;
    rhs.f = two;
    return lhs.i < rhs.i;
}

bool compare2(float one, float two) {
    return reinterpret_cast<TypeWithSameSizeAsFloat&>(one) 
         < reinterpret_cast<TypeWithSameSizeAsFloat&>(two);
}

了解警告,并仔细选择第二种类型。无论如何,它几乎毫无价值。

答案 3 :(得分:2)

也许我误解了这个问题,但我想你可以这样做:

bool compare(float a, float b)
{
    return *((unsigned int*)&a) < *((unsigned int*)&b);
}

但这假定了各种各样的事情,并且还保证了为什么你想要比较两个浮点数的按位表示的问题。