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

Does precision change slightly during casting int to double in Java?

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

因此,有时浮点数的精度会因其表示方式(科学符号,带指数和尾数)而改变。

但是如果我将整数值转换为加倍,有没有机会改变Java中的双精度?

我是说,

1
2
3
4
    int i = 3;
    double d = (double) i;

    System.out.println(d);

我得到了预期的3.0输出。

但是,由于Java中的双重表示方式,是否有可能像EDCOX1×1那样精确地改变?


不适用于int到double,但您可以使用long到double(或int到float):

  • 并非所有大于2^53-1或小于-2^53的多头都能精确地用一个双精度数表示;
  • 不是所有大于2^24-1的整数(或小于-2^24的整数)都能精确地用浮点表示。

这种限制是因为用来表示尾数的位数(双数53位,浮点数24位)。


您可以迭代i,直到找到一个2**i双精度,等于2**i + 1

1
2
3
4
5
6
7
8
9
10
11
12
13
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.");
    }
}

它输出:

1
Loss of precision is greater than 1.0 for 2**53 when using double.

这证实了接受的答案。

注意,在javascript中,没有整数类型,而是使用了double(它们称为Numbers)。如果它们足够大,则连续的Number可以相等。