【发布时间】:2011-09-04 05:41:03
【问题描述】:
double d = 4.321562;
有没有一种简单的方法可以从 d 中自行提取 0.321562?我试着在数学课上找,但没有运气。如果这可以在不转换为字符串或强制转换为其他任何内容的情况下完成,那就更好了。
【问题讨论】:
标签: java math numbers double decimal-point
double d = 4.321562;
有没有一种简单的方法可以从 d 中自行提取 0.321562?我试着在数学课上找,但没有运气。如果这可以在不转换为字符串或强制转换为其他任何内容的情况下完成,那就更好了。
【问题讨论】:
标签: java math numbers double decimal-point
好吧,你可以使用:
double x = d - Math.floor(d);
请注意,由于二进制浮点的工作方式,它不会准确地为您提供 0.321562,因为原始值不是准确地 4.321562。如果您真的对精确数字感兴趣,您应该改用BigDecimal。
【讨论】:
x - (int)x。正数和负数都可以正常转换。否则,Math.floor() 将使用“小于或等于参数的最正(最接近正无穷大)整数值”。示例:-123.25 - (int)(-123.25) 将导致 -0.25,因此您可以决定如何处理符号。 Math.floor() 的使用将给出 `0.75' 的正数
不使用 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 的精度有限,如果您不使用适当的舍入,您可能会看到表示问题蔓延。这可能发生在您使用 double esp 数字的任何计算中,这些数字不是 2 的幂的精确和。
【讨论】:
double对任何数学进行适当舍入的必要性
使用模数:
double d = 3.123 % 1;
assertEquals(0.123, d,0.000001);
【讨论】: