Второй вопрос, который вы задаете, касается размера ulp в Java.
Если ulp превышает 1/(n)
, то округление умножения не приведет к восстановлению исходного деленного целого числа.Как правило, большие язвы связаны с большими двойными значениями.Ульпа, связанная с двойным, начинает превышать 1 в районе 9E15;если ваши восстановленные двойники были там, то вы могли бы найти проблемы с round (), не получив ожидаемого ответа.Однако, когда вы работаете со значениями типа int, наибольшее значение числителя вашего деления будет Integer.MAX_VALUE
.
Следующая программа проверяет все положительные целые значения n
, чтобы определить, какое из них вызываетНаибольший потенциал ошибки округления при попытке восстановить разделенное целое число:
public static void main(String[] args)
{
// start with large number
int m = Integer.MAX_VALUE;
double d = 0;
double largestError = 0;
int bigErrorCause = -1;
for (int n = 1; n < Integer.MAX_VALUE; n++)
{
d = (double) m / n;
double possibleError = Math.ulp(d) * n;
if (possibleError > largestError)
{
largestError = possibleError;
bigErrorCause = n;
}
}
System.out.println("int " + bigErrorCause + " causes at most "
+ largestError + " error");
}
Выходные данные:
int 1073741823 вызывает не более 4,768371577590358E-7 ошибка
Округление с использованием Math.round, затем приведение к int должно восстановить исходное значение int.