在转换int期间精度是否会稍微改变,以便在Java中加倍?

Uzz*_*der 25 java precision casting

我读过这个 - 为什么浮点数不准确?

因此,有时精度可以在浮点数中改变,因为它的表示风格(带有指数和尾数的科学记数法).

但是如果我将一个整数值转换为double,是否有机会在Java中稍微改变double的精度?

我的意思是,

    int i = 3;
    double d = (double) i;

    System.out.println(d);
Run Code Online (Sandbox Code Playgroud)

我得到的输出3.0正如我所料.

但是,有没有机会像3.000001Java中的双重表示风格那样进行精确更改?

And*_*ner 33

不是int要加倍,但你可能需要长一倍(或int to float):

  • 并非所有大于2^53-1(或小于-2^53)的长度都可以用双精确表示;
  • 并非所有大于2^24-1(或小于-2^24)的整数都可以由浮点数精确表示.

这种限制是因为用于表示尾数的位数(双精度数为53,浮点数为24).

  • @Ben这么简单的检查可能会产生误导:你可能碰巧选择`Integer.MIN_VALUE`来测试它,你会发现'Integer.MIN_VALUE`*可以*完全表示为一个浮点数和一个双精度数.恰好它适用于`Integer.MAX_VALUE`. (4认同)
  • 证明"规则"是错误只需要一个例外.仅仅因为`Integer.MAX_VALUE`'恰好'正常工作并不会使证明案件不可靠 (3认同)

Eri*_*nil 5

您可以遍历i,直到找到一个2**i双等于2**i + 1:

import java.util.stream.IntStream;

public class PrecisionLoss
{
    public static void main(String[] args) {
        double epsilon = 1;
        Integer maxInt = IntStream.iterate(0, i -> i + 1)
                .filter(i -> Math.pow(2, i) == Math.pow(2, i) + epsilon)
                .findFirst().getAsInt();
        System.out.println("Loss of precision is greater than " + epsilon
                + " for 2**" + maxInt + " when using double.");
    }
}
Run Code Online (Sandbox Code Playgroud)

它输出:

Loss of precision is greater than 1.0 for 2**53 when using double.
Run Code Online (Sandbox Code Playgroud)

这证实了公认的答案.

请注意,在Javascript中,没有整数类型,而是使用双精度(它们被称为Numbers).如果它们足够大,则连续的Numbers可以彼此相等.