Java中的int
和float
都是32位大小的值。是否可以编写一对函数
int toInt(float f);
float toFloat(int n);
如果f1
和f2
是任意float
非NaN值且i1和i2是任意int
值:
f1 < f2
当且仅当toInt(f1) < toInt(f2)
f1 > f2
当且仅当toInt(f1) > toInt(f2)
f1 == f2
当且仅当toInt(f1) == toInt(f2)
toInt(toFloat(i1) == i1
toFloat(toInt(f1)) == f1
编辑:我已经编辑了问题以排除浮动的NaN值,这要归功于答案,说明这些问题会发生什么。
答案 0 :(得分:7)
是。 IEEE floats和双打的排列方式使您可以通过对原始二进制表示进行 无符号 比较来比较它们。从float转换为原始整数和返回的函数是java.lang.Float.floatToIntBits和java.lang.Float.intBitsToFloat。这些功能是处理器内在函数,因此它们的成本极低。
多头和双打也是如此。转化函数包括java.lang.Double.doubleToLongBits和java.lang.Double.longBitsToDouble。
请注意,如果要对整数使用正常的 签名 比较,除了转换为整数之外,还必须进行一些额外的转换。
此规则的唯一例外是NaN,无论如何都不允许总排序。
答案 1 :(得分:1)
我明白你在说什么。起初我对你的问题有不同的解释。正如其他人都提到的那样:是的。使用描述here和here的文章解释为什么我们应该使用@Peter Lawrey描述的方法来比较整数和浮点数之间的基础位模式
答案 2 :(得分:1)
您可以使用
int n = Float.floatToRawIntBits(f);
float f2 = Float.intBitToFloat(n);
int n2 = Float.floatToRawIntBits(f2);
assert n == n2; // always
assert f == f2 || Float.isNaN(f);
作为int
的原始位与原始float
具有相同的排序顺序,但NaN
值除外,float
值不具有int
值值为NaN
注意:float
有多个值彼此不相等{{1}}
答案 3 :(得分:1)
不,你不能
有2 ^ 32个可能的int值,所有这些值都是不同的。 但是,你不到2 ^ 32个花车;即。 7FF0000000000001至7FF7FFFFFFFFFFFF代表NaN&#39; s,
因此,你有更多的int而不是浮点数,因为toFloat(i1)
不会为每个int生成一个独特的浮点数而无法明确地将它们相互映射
答案 4 :(得分:1)
RüdigerKlaehn的答案给出了正常情况,但缺乏一些细节。双射仅在漂亮且干净的浮动域中退出。
注意:IEEE浮点数的表示形式为sign_bit(1 bit) exponent(8 bits) sinificand(23 bits)
,而 clean 情况下的值为(-1)<sup>sign</sup> * 2<sup>exp</sup> * significand
。实际上,23位代表实际有效数的小数部分,整数部分为1。
0 < exp < 255
(对应于普通非null浮点数)的所有内容都可以作为无符号字节使用,并且在该域中你有一个双射。
对于exp == 255
,您的无限值为significand == 0
,所有NaN都为significand != 0
- 好的,您明确地排除了它们。
但对于exp == 0
,仍有奇怪的事情:当significand == 0
时你有+0和-0。我不确定他们是否被认为是平等的。如果有人知道,请随时编辑帖子。但作为整数值,它们当然会有所不同。
当exp == 0
和significand != 0
找到非规范化数字时...虽然不相等,但会转换为最小数字0的0,而不是0。
因此,如果你想要一个双射,只使用带有0 < exp < 255<
的普通数字,并避免NaN,无限,0和非正规数字,其中 怪异。
参考文献:
答案 5 :(得分:0)
f1 == f2
是不可能的,有关详细信息,请参阅this answer。如果您确实想要进行等式检查,则需要包含增量。