Java中的float与double转换-上下限是多少?

4

正如大多数人所知,从double转换为float会损失精度。这意味着,多个double值可能映射到同一个float值。

但是,如何进行相反的操作?给定一个普通的(我不关心极端情况)float值,如何找到仍然映射到同一float值的双精度上限和下限?

或者,用代码说:

function boolean testInterval(float lowF, float highF, double queryD) {
    float queryF = (float) queryD;
    return (lowF <= queryF) && (queryF <= highF);
}

并且

function boolean testInterval(float lowF, float highF, double queryD) {
    double lowD = (double) lowF;
    double highD = (double) highF;
    return (lowD <= queryD) && (queryD <= highD);
}

不总是返回相同的结果。我正在寻找两个函数float-> double,使第二个函数返回与第一个函数相同的结果。

这可能有效,但对我来说看起来像是一种妥协措施,而不是正确的解决方案。

function boolean testIntervalHack(float lowF, float highF, double queryD) {
    double lowD = (double) lowF - Float.MIN_VALUE;
    double highD = (double) highF + Float.MIN_VALUE;
    return (lowD <= queryD) && (queryD <= highD);
}
1个回答

3
你的testIntervalHack不起作用,映射到相同float值的double值范围是不同的。例如,对于x = 2 ^ 24-1,在x-0.5x + 0.5之间的每个double将被映射到相同的值(xfloat值),但是x +/- Float.MIN_VALUE == x
我不知道有任何方便的API方法,所以我能提供的最好的方法是:
  1. 转换为double
  2. 通过doubleTo(Raw)LongBitsdouble转换为位表示形式
  3. 添加或减去2 28或2 28-1中的一个,具体取决于您想要上限还是下限,以及2 29位是0还是1(因为四舍五入)
  4. 通过longBitsToDouble将该长整型转换为双精度数
嗯,这适用于float范围内的有限值。对于NaN,可以在第1步后停止,对于无穷大,需要更加谨慎,因为大于或等于2 128-2 103double值将转换为(float)Infinity,这与(double)Infinity的位表示形式相差很远。

谢谢。无穷大和NaN超出了我的范围。我担心我需要直接使用位表示。 :-( - Has QUIT--Anony-Mousse
所以我似乎已经让NaN、Infinity、+-0和正常值正常工作了。我还没有注意到2^29位。你能详细说明一下吗?而且我仍然在处理次正常值时遇到麻烦。 - Has QUIT--Anony-Mousse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接