如何获得浮点数的小数部分?
我需要提取一个浮点数的小数部分,但我得到奇怪的结果:
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);