Превращает ли точность во время отливки int в Java?
Я прочитал это - почему числа с плавающей точкой неточны?
Таким образом, иногда точность может быть изменена числом с плавающей запятой из-за ее стиля представления (научная нотация с показателем и мантисса).
Но если я добавлю целочисленное значение в double, есть ли шанс немного изменить точность двойного в Java?
Я имею в виду,
int i = 3;
double d = (double) i;
System.out.println(d);
на выходе я получил 3.0
как я и ожидал.
но, есть ли вероятность того, что точность изменилась, как 3.000001
из-за стиля представления double в Java?
Ответы
Ответ 1
Не для int double, но вы можете долго удваивать (или int плавать):
- Не все
2^53-1
(или меньше -2^53
) могут быть представлены в точности двойным; - Не все ints больше
2^24-1
(или меньше -2^24
) могут быть представлены точно поплавком.
Это ограничение возникает из-за количества бит, используемых для представления мантиссы (53 в парном разряде, 24 в поплавках).
Ответ 2
Вы можете перебирать i
до тех пор, пока не найдете 2**i
double, который равен 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.");
}
}
Он выводит:
Loss of precision is greater than 1.0 for 2**53 when using double.
Что подтверждает принятый ответ.
Обратите внимание, что в Javascript нет целочисленного типа, и вместо него используются удвоения (они называются Number
s). Если они достаточно большие, последовательный Number
может быть равен друг другу.