La segunda pregunta que hace se refiere a cuán grande es ulp en Java.
Si el ulp supera 1/(n)
, redondear la multiplicación no recuperaría el original dividido int. Típicamente, los ulps más grandes están asociados con valores dobles más grandes. Un ulp asociado con un doble comienza a exceder 1 en alrededor de 9E15; si tus dobles recuperados estaban por allí, entonces podrías encontrar problemas con round() que no obtuviera la respuesta esperada. Sin embargo, como está trabajando con valores int, el valor más grande del numerador de su división será Integer.MAX_VALUE
.
las siguientes pruebas del programa todos los valores enteros positivos de n
para ver cuál hace que el mayor potencial de error de redondeo cuando se trata de recuperar el int dividida:
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");
}
la salida es:
int 1073741823 causa a lo sumo 4.768371577590358E-7 error
Redondeando eso usando Math.round, entonces fundir a int debería recuperar el int original.
No es una pregunta tonta; la pregunta plantea algunos problemas sutiles acerca de la aritmética de coma flotante y la "capacidad de recuperación" de los enteros. – Nayuki
muchas preguntas flotantes en este sitio últimamente - hmm ... –