0

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

Kazekage Gaara
  • 14,972
  • 14
  • 61
  • 108
Scorpion
  • 6,831
  • 16
  • 75
  • 123

2 Answers2

5

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);
Community
  • 1
  • 1
Kazekage Gaara
  • 14,972
  • 14
  • 61
  • 108
0

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.

Sean Owen
  • 66,182
  • 23
  • 141
  • 173
  • Can you please kindly help me in this. How can i get exact floating point. – Scorpion Jun 24 '12 at 08:38
  • 1
    Read the javadoc for `java.math.BigDecimal` first please. Start with `BigDecimal kmVal = new BigDecimal(kms.getText().toString());` – Sean Owen Jun 24 '12 at 08:44