问题
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
回答1:
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.
Read this and this for more.
For precision use BigDecimal:
BigDecimal test = new BigDecimal("0.1");
test = test.add(new BigDecimal("0.1"));
System.out.println(test);
回答2:
If you really need exact representation of floating-point values, then indeed you can't use simple floating point types like double
or float
in any language. In Java, you could use BigDecimal
. But, I'd first figure out whether you really need this exact floating-point or not.
来源:https://stackoverflow.com/questions/11175922/issue-with-float-increment-in-android