【问题标题】:Java float to double - upper and lower bounds?Java float to double - 上限和下限?
【发布时间】:2012-01-05 23:01:39
【问题描述】:

正如这里的大多数人都知道的那样, double -> 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 以使第二个函数在第一个函数返回相同的结果。

这可行,但它看起来像一个 hack,对我来说不是正确的解决方案。

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);
}

【问题讨论】:

    标签: java floating-point double precision ieee-754


    【解决方案1】:

    您的testIntervalHack 不起作用,映射到相同floatdouble 值范围会有所不同。例如,对于x = 2^24-1x-0.5x+0.5 之间的每个double 都将映射到相同的值(xfloat 值),但x +/- Float.MIN_VALUE == x

    我不知道有什么方便的 API 方法,所以我能提供的最好的方法是

    1. 转换为double
    2. 通过doubleTo(Raw)LongBitsdouble转换为位表示
    3. 添加或减去 228 或 228-1 之一,具体取决于您想要上限还是下限以及 229-bit 为 0 或 1(因为取整)
    4. 通过longBitsToDouble将long转换为double

    嗯,这是float 范围内的有限值。对于NaNs,您可以在第 1 步之后停止。对于无穷大,它有点微妙,因为 double 的值大于或等于 2128-2103 sup> 被转换为(float)Infinity,这与(double)Infinity 的位表示相距甚远。

    【讨论】:

    • 谢谢。 Infinites 和 NaN 超出了我的范围。我担心我已经需要使用位表示了。 :-(
    • 所以我似乎让它适用于 NaN、Infinity、+-0 和正常值。我还没有注意 2^29 位。你能详细说明一下吗?而且我仍然遇到低于正常值的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多