如何在Java中获取小数点后面的数字?

24
 double d = 4.321562;

有没有一种简单的方法可以从d中单独提取0.321562?我尝试在math类中查找,但没有找到合适的函数。如果不必将其转换为字符串或强制转换为其他类型就能实现,那就更好了。

3个回答

33

好的,你可以使用:

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

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


3
不要使用这个,而是进行强制类型转换:x - (int)x。强制类型转换可以正确地处理正数和负数。否则,Math.floor()会使用“最接近参数且小于或等于该参数的最正整数值”。例如:-123.25 - (int)(-123.25)将得到-0.25,因此您可以决定如何处理符号。使用Math.floor()将得到0.75的正值。 - Dmitry Gryazin
1
@Bagzerg:同意,不过转换为 long 比转换为 double 更好,可以处理 int 范围之外的值。我有机会时会编辑并提到两者。 - Jon Skeet

29

另一种在不使用Math的情况下获取分数的方法是将其转换为long类型。

double x = d - (long) d;
当你打印一个双精度浮点数时,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 进行计算的情况下,特别是对于那些不是2的幂次方的确切数字。


1
如果您的数字大于32,例如32.59,则此系统将失败。31.59d - (long)31.59的结果与32.59d - (long)32.59不同。 - Hari
1
@Hari 我已经添加了一条注释,提醒在使用 double 进行任何数学计算时需要适当进行四舍五入。 - Peter Lawrey

10

使用模运算:

double d = 3.123 % 1;
assertEquals(0.123, d,0.000001);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接