在Android中浮动增量问题 [英] issue with float increment in Android
问题描述
float kmVal = 0.0f;
EditText kms =(EditText)findViewById(R.id.km);
kmVal = Float.valueOf(kms.getText()。toString());
单击按钮我正在增加值。
kmVal + = 0.1;
kms.setText(String.valueOf(kmVal));
记录:
pre> 06-24 13:16:21.644:I / System.out(958):Value == 0.1
06-24 13:16:21.644:I / System.out(958):字符串值== 0.1
06-24 13:16:21.886:D / SntpClient(61):请求时间失败:java.net.SocketException:不支持协议的地址系列
06-24 13:16:22.145:I / System.out(958):Value == 0.2
06-24 13:16:22.145:I / System.out(958):String Value == 0.2
06-24 13:16:22.384:I / System.out(958):Value == 0.3
06-24 13:16:22.384:I / System.out(958):String值== 0.3
06-24 13:16:22.484:I / System.out(958):Value == 0.4
06-24 13:16:22.484:I / System.out(958 ):String Value == 0.4
06-24 13:16:22.684:I / System.out(958):Value == 0.5
06-24 13:16:22.684:I / System。 (958):字符串值== 0.5
06-24 13:16:22.868:I / System.out(958):值== 0.6
06-24 13:16:22.874:I /System.out(958): String Value == 0.6
06-24 13:16:23.056:I / System.out(958):Value == 0.70000005
06-24 1 3:16:23.064:I / System.out(958):String Value == 0.70000005
06-24 13:16:23.884:I / System.out(958):Value == 0.8000001
06-24 13:16:23.884:I / System.out(958):String Value == 0.8000001
06-24 13:16:23.964:D / dalvikvm(353):GC_EXPLICIT已释放7K,44% 3532K / 6279K,外部716K / 1038K,暂停106ms
06-24 13:16:24.536:I / System.out(958):值== 0.9000001
06-24 13:16:24.536: I / System.out(958):String Value == 0.9000001
正如您从日志值高达0.6是好的,但在此之后,其增加额外的数字,我不想要的。我不知道为什么我会得到这样的结果。如果有人有任何想法,请帮助。
谢谢 这是因为如何表示浮点型数字。从 JLS :
lockquote>
任何浮点值集的有限非零值都可以表示为s·m·2(e - N + 1),其中s是+1或-1,m是小于2N的正整数,e是Emin = - (2K-1-2)和Emax = 2K-1-1之间的整数,并且其中N和K是取决于值集合的参数。
因此,float值不能准确地表示基数为10的实数。虽然你可能会得到最初的 0.1
,但实际发生的是你得到 0.0999999999999999996
,它变成了 0.1
。但是当你继续对它进行操作的时候,它一直在失去精确度。
精确使用 BigDecimal :
$ b
BigDecimal test =新的BigDecimal(0.1);
test = test.add(new BigDecimal(0.1));
System.out.println(test);
I am trying to increment value of float by 0.1 every time. But i am getting very strange result some time.
float kmVal = 0.0f;
EditText kms = (EditText) findViewById(R.id.km);
kmVal = Float.valueOf(kms.getText().toString());
On Click of button I am incrementing the value.
kmVal += 0.1;
kms.setText(String.valueOf(kmVal));
LOG :-
06-24 13:16:21.644: I/System.out(958): Value ==0.1
06-24 13:16:21.644: I/System.out(958): String Value ==0.1
06-24 13:16:21.886: D/SntpClient(61): request time failed: java.net.SocketException: Address family not supported by protocol
06-24 13:16:22.145: I/System.out(958): Value ==0.2
06-24 13:16:22.145: I/System.out(958): String Value ==0.2
06-24 13:16:22.384: I/System.out(958): Value ==0.3
06-24 13:16:22.384: I/System.out(958): String Value ==0.3
06-24 13:16:22.484: I/System.out(958): Value ==0.4
06-24 13:16:22.484: I/System.out(958): String Value ==0.4
06-24 13:16:22.684: I/System.out(958): Value ==0.5
06-24 13:16:22.684: I/System.out(958): String Value ==0.5
06-24 13:16:22.868: I/System.out(958): Value ==0.6
06-24 13:16:22.874: I/System.out(958): String Value ==0.6
06-24 13:16:23.056: I/System.out(958): Value ==0.70000005
06-24 13:16:23.064: I/System.out(958): String Value ==0.70000005
06-24 13:16:23.884: I/System.out(958): Value ==0.8000001
06-24 13:16:23.884: I/System.out(958): String Value ==0.8000001
06-24 13:16:23.964: D/dalvikvm(353): GC_EXPLICIT freed 7K, 44% free 3532K/6279K, external 716K/1038K, paused 106ms
06-24 13:16:24.536: I/System.out(958): Value ==0.9000001
06-24 13:16:24.536: I/System.out(958): String Value ==0.9000001
As you can see from the log that the value upto 0.6 are ok but after that its adding extra digits that i don't want. I don't know why i am getting such result. If anyone has any idea please kindly help.
Thanks
This is because how the floating type numbers are represented. From the JLS:
The finite nonzero values of any floating-point value set can all be expressed in the form s · m · 2(e - N + 1), where s is +1 or -1, m is a positive integer less than 2N, and e is an integer between Emin = -(2K-1-2) and Emax = 2K-1-1, inclusive, and where N and K are parameters that depend on the value set.
Hence, float values cannot accurately represent base 10 real numbers. While you might get the initial 0.1
, what actually happens is you are getting 0.0999999999999999996
which is turned into 0.1
. But as you keep on doing operations on it, it keeps losing precision.
For precision use BigDecimal:
BigDecimal test = new BigDecimal("0.1");
test = test.add(new BigDecimal("0.1"));
System.out.println(test);
这篇关于在Android中浮动增量问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!