如何获得浮点数的小数部分?

我需要提取一个浮点数的小数部分,但我得到奇怪的结果:

float n = 22.65f; // I want x = 0.65f, but... x = n % 1; // x = 0.6499996 x = n - Math.floor(n); // x = 0.6499996185302734 x = n - (int)n; // x = 0.6499996 

为什么会这样呢? 为什么我得到这些值而不是0.65

float只有几个精度的数字,所以你应该期望相当容易看到一个圆的错误。 尝试double这更有准确性,但仍有四舍五入的错误。 你必须围绕任何答案你有一个理智的输出。

如果这不是渴望的,你可以使用BigDecimal没有舍入错误,但有自己的头痛恕我直言。

编辑:你可能会觉得这很有趣。 默认的Float.toString()使用最小舍入,但通常是不够的。

 System.out.println("With no rounding"); float n = 22.65f; System.out.println("n= "+new BigDecimal(n)); float expected = 0.65f; System.out.println("expected= "+new BigDecimal(expected)); System.out.println("n % 1= "+new BigDecimal(n % 1)); System.out.println("n - Math.floor(n) = "+new BigDecimal(n - Math.floor(n))); System.out.println("n - (int)n= "+new BigDecimal(n - (int)n)); System.out.println("With rounding"); System.out.printf("n %% 1= %.2f%n", n % 1); System.out.printf("n - Math.floor(n) = %.2f%n", n - Math.floor(n)); System.out.printf("n - (int)n= %.2f%n", n - (int)n); 

打印

 With no rounding n= 22.6499996185302734375 expected= 0.64999997615814208984375 n % 1= 0.6499996185302734375 n - Math.floor(n) = 0.6499996185302734375 n - (int)n= 0.6499996185302734375 With rounding n % 1= 0.65 n - Math.floor(n) = 0.65 n - (int)n= 0.65 

我认为这将是最简单的方法:

 float n = 22.65f; float x = n - (int) n; 

我有点长,但工作:

 BigDecimal.valueOf(2.65d).divideAndRemainder(BigDecimal.ONE)[1].floatValue() 

因为并非所有的有理数都可以表示为浮点数,而0.6499996...0.65的最接近的近似值。

例如,尝试打印数字0.65前20位:

  System.out.printf("%.20f\n", 0.65f); 

– >

  0.64999997615814210000 

编辑
正如其他人所指出的,在计算过程中积累的四舍五入误差也是其中的一部分。

如果您只想将数字打印到2dp,则可以使用DecimalFormat。

 DecimalFormat df= new DecimalFormat("#.##"); System.out.println(df.format(f)); 

如果你想在内部使用定点数字使用BigDecimal

声音和完美的方式来获取浮点数和双精度数据types的小数部分,就像这样的代码使用string:

 float num=2.35f; String s= new Float(num).toString(); String p=s.substring(s.indexOf('.')+1,s.length()); int decimal=Integer.parseInt(p); 

尝试这个。 如果计时器是10.65,那么h将以小数点后两位* 100 = 65结束。

这是一个快速和简单的方法来分离你想要的,而不是四舍五入的问题。

 float h = (int)((timer % 1) * 100); 

简短的回答:你不能完全用二进制表示一些十进制的“确切”的数字。

长答案: http : //www-users.math.umd.edu/~jkolesar/mait613/floating_point_math.pdf

[编辑]

另外一个有趣的阅读: http : //www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf

试试java.math.BigDecimal

此代码将适用于任意数量的十进制数字。

 float f = 2.3445f; String s = Float.toString(f); char[] c = s.toCharArray(); int length = s.length(); int flag = 0; StringBuilder n = new StringBuilder(); for(int i = 0; i < length; i++) { if(flag == 1) { n.append(c[i]); } if(c[i] == '.') { flag = 1; } } String result = n.toString(); int answer = Integer.parseInt(result); System.out.println(answer);