24
 double d = 4.321562;

有没有一种简单的方法可以从 d 中自己提取 0.321562?我试着在数学课上找,但没有运气。如果这可以在不转换为字符串或强制转换为其他任何内容的情况下完成,那就更好了。

4

3 回答 3

32

好吧,您可以使用:

double x = d - Math.floor(d);

请注意,由于二进制浮点的工作方式,它不会给你准确的 0.321562,因为原始值不完全是4.321562。如果您真的对精确数字感兴趣,则应BigDecimal改为使用。

于 2011-05-29T08:44:45.183 回答
28

不使用 Math 获得分数的另一种方法是转换为 long。

double x = d - (long) d;

当您打印时double, toString 将执行少量舍入,因此您不会看到任何舍入错误。但是,当你去掉整数部分,四舍五入就不够了,四舍五入的误差就变得很明显了。

解决此问题的方法是自己进行舍入或使用 BigDecimal 来控制舍入。

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));

印刷

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

注意:double精度有限,如果您不使用适当的舍入,您会看到表示问题蔓延。这可能发生在您使用doubleesp 数字的任何计算中,这些数字不是 2 的幂的精确总和。

于 2011-05-29T08:59:27.307 回答
10

使用模数:

double d = 3.123 % 1;
assertEquals(0.123, d,0.000001);
于 2012-07-30T15:19:33.867 回答