Otra forma de obtener la fracción sin usar Matemáticas es lanzar a largo.
double x = d - (long) d;
Al imprimir un double
el toString realizará una pequeña cantidad de redondeo por lo que no se ve ningún error de redondeo. Sin embargo, cuando elimina la parte entera, el redondeo ya no es suficiente y el error de redondeo se vuelve obvio.
La forma de evitar esto es hacer el redondeo sí mismo o usar BigDecimal que le permite controlar el redondeo.
double d = 4.321562;
System.out.println("Double value from toString " + d);
System.out.println("Exact representation " + new BigDecimal(d));
double x = d - (long) d;
System.out.println("Fraction from toString " + x);
System.out.println("Exact value of fraction " + new BigDecimal(x));
System.out.printf("Rounded to 6 places %.6f%n", x);
double x2 = Math.round(x * 1e9)/1e9;
System.out.println("After rounding to 9 places toString " + x2);
System.out.println("After rounding to 9 places, exact value " + new BigDecimal(x2));
impresiones
Double value from toString 4.321562
Exact representation 4.321562000000000125510268844664096832275390625
Fraction from toString 0.3215620000000001
Exact value of fraction 0.321562000000000125510268844664096832275390625
Rounded to 6 places 0.321562
After rounding to 9 places toString 0.321562
After rounding to 9 places, exact value 0.32156200000000001448796638214844278991222381591796875
no utilice este, hacen que la fundición en su lugar: 'x - (int) x'. La conversión funcionará correctamente con números positivos y negativos. De lo contrario, 'Math.floor()' usará "el valor entero más positivo (más cercano al infinito positivo) menor o igual que el argumento". Ejemplo: '-123.25 - (int) (- 123.25)' dará como resultado -0.25, por lo que puede decidir qué hacer con el signo. El uso de 'Math.floor()' arrojará positivo de '0.75' –
@Bagzerg: De acuerdo, aunque el lanzamiento a largo sería mejor que el lanzamiento al doble, para manejar valores fuera del rango de int. Editaré para mencionar ambos cuando tenga la oportunidad. –