假设我想要一个接受两个浮点数(x和y)的函数,并且我希望不使用它们的float表示,而是使用它们作为32位unsigned int的逐位表示来比较它们。也就是说,像-495.5这样的数字具有位表示0b11000011111001011100000000000000或0xC3E5C000作为float,而我有一个具有相同位表示的unsigned int (对应于十进制值3286614016,我不关心它)。有没有什么简单的方法可以让我只使用它们各自的unsigned int副本中包含的信息来对这些浮点数执行像<=这样的操作?
发布于 2010-04-06 14:25:39
除非确保所有原始值都为正数,否则必须执行带符号比较。必须使用与原始浮点类型大小相同的整数类型。每个芯片可能具有不同的内部格式,因此将来自不同芯片的值作为整数进行比较最有可能给出误导性的结果。
大多数浮点格式看起来像这样:sxxxmmmm
s是一个符号位
xxx是一个指数
mmmm是尾数
然后,表示的值将类似于:1mmm << (xxx-k)
1mmm,因为存在隐含的前导1位,除非该值为零。
如果是xxx < k,那么这将是一个右移位。k接近但不等于xxx可以表示的最大值的一半。它根据尾数的大小进行了调整。
总而言之,忽略NaN,将浮点值作为相同大小的有符号整数进行比较将产生有意义的结果。它们是这样设计的,这样浮点比较的开销不会比整数比较高。有一些编译器优化可以关闭NaN检查,这样如果芯片的浮点格式支持的话,比较就是直接的整数比较。
作为整数,NaN大于无穷大,大于有限值。如果您尝试无符号比较,则所有负值都将大于正值,就像有符号整数转换为无符号整数一样。
发布于 2010-04-06 11:28:53
如果你真的不关心转换的结果是什么,这并不太难。但结果是非常不可移植的,而且几乎可以肯定的是,您不会得到一个与直接比较浮点数所得到的排序完全相似的排序。
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);
}只需理解注意事项,并仔细选择第二种类型即可。无论如何,这是一个几乎毫无价值的摘录。
发布于 2010-04-06 11:06:27
简而言之,不是。IEEE754可能允许某些类似的黑客攻击,但它们并不总是有效且可处理所有情况,而且一些平台不使用浮点标准(例如内部精度为80位的x87上的doubles )。
如果您这样做是出于性能原因,我建议您强烈建议重新考虑--如果使用整数比较更快,编译器可能会为您这样做,如果不是这样,您需要多次进行浮点数到整数的转换,而不需要将浮点数移出寄存器就可以进行简单的比较。
https://stackoverflow.com/questions/2582417
复制相似问题