比较浮点数的位表示
假设我想要一个带有两个浮点数( x
和y
)的函数,我想比较它们不使用它们的float
表示,而是将它们的按位表示forms作为32位unsigned int
。 也就是说,像-495.5
这样的-495.5
具有位表示0b11000011111001011100000000000000
或0xC3E5C000
作为float
,并且我有一个具有相同位表示的unsigned int
(对应于十进制值3286614016
,我不关心)。 有没有简单的方法让我只使用各自的unsigned int
对应物中包含的信息对这些浮点数执行<=
这样的操作?
您必须进行签名比较,除非您确保所有原始值都是正数。 必须使用与原始浮点类型大小相同的整数类型。 每个芯片可能具有不同的内部格式,因此将来自不同芯片的值作为整数进行比较最有可能产生误导性结果。
大多数浮动格式看起来像这样: sxxxmmmm
s
是一个标志位
xxx
是指数
mmmm
是尾数
表示的值将是: 1mmm << (xxx-k)
1mmm
因为除非值为零,否则隐含前导1
位。
如果xxx < k
那么它将是右移。 k
接近但不等于xxx
可以表示的最大值的一半。 它根据尾数的大小进行调整。
可以这么说,无视NaN
,将浮点值作为相同大小的有符号整数进行比较将产生有意义的结果。 它们的设计方式使得浮点比较不会比整数比较更昂贵。 有编译器优化来关闭NaN
检查,以便比较是直接整数比较,如果芯片的浮点格式支持它。
作为整数, NaN
大于无穷大大于有限值。 如果您尝试无符号比较,则所有负值都将大于正值,就像转换为无符号的有符号整数一样。
总之,没有。 IEEE 754可能允许这样的某些类型的黑客,但它们不能一直工作并处理所有情况,并且一些平台不使用该浮点标准(例如x87内部具有80位精度的双打)。
如果你出于性能原因这样做,我建议你强烈重新考虑 – 如果使用整数比较更快,编译器可能会为你做,如果不是,你需要多次支付浮点到int转换,当可以在不将寄存器移出寄存器的情况下进行简单比较时。
如果你真的真的不关心转换率是多少,那就不难了。 但结果是非常不便携的,你几乎肯定不会得到一个完全类似你通过直接比较浮点数获得的顺序。
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(one) < reinterpret_cast(two); }
只需了解警告,并仔细选择第二种类型。 无论如何,它几乎毫无价值。
也许我误解了这个问题,但我想你可以这样做:
bool compare(float a, float b) { return *((unsigned int*)&a) < *((unsigned int*)&b); }
但这假定了各种各样的事情,并且还保证了为什么你想要比较两个浮点数的按位表示的问题。