Java浮点数和整数保持顺序之间的双射

时间:2014-07-26 20:55:28

标签: java casting int

Java中的intfloat都是32位大小的值。是否可以编写一对函数

int toInt(float f);
float toFloat(int n);

如果f1f2是任意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值,这要归功于答案,说明这些问题会发生什么。

6 个答案:

答案 0 :(得分:7)

是。 IEEE floats和双打的排列方式使您可以通过对原始二进制表示进行 无符号 比较来比较它们。从float转换为原始整数和返回的函数是java.lang.Float.floatToIntBitsjava.lang.Float.intBitsToFloat。这些功能是处理器内在函数,因此它们的成本极低。

多头和双打也是如此。转化函数包括java.lang.Double.doubleToLongBitsjava.lang.Double.longBitsToDouble

请注意,如果要对整数使用正常的 签名 比较,除了转换为整数之外,还必须进行一些额外的转换。

此规则的唯一例外是NaN,无论如何都不允许总排序。

答案 1 :(得分:1)

我明白你在说什么。起初我对你的问题有不同的解释。正如其他人都提到的那样:是的。使用描述herehere的文章解释为什么我们应该使用@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 == 0significand != 0找到非规范化数字时...虽然不相等,但会转换为最小数字0的0,而不是0。

因此,如果你想要一个双射,只使用带有0 < exp < 255<普通数字,并避免NaN,无限,0和非正规数字,其中 怪异。

参考文献:

答案 5 :(得分:0)

f1 == f2

是不可能的,有关详细信息,请参阅this answer。如果您确实想要进行等式检查,则需要包含增量。