0

我试图每次将 float 的值增加 0.1。但有一段时间我得到了非常奇怪的结果。

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));

日志 :-

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

正如您从日志中看到的那样,最高 0.6 的值是可以的,但在那之后它添加了我不想要的额外数字。我不知道为什么我会得到这样的结果。如果有人有任何想法,请提供帮助。

谢谢

4

2 回答 2

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);
于 2012-06-24T08:20:40.453 回答
0

如果您确实需要浮点值的精确表示,那么您确实不能使用简单的浮点类型,例如double任何float语言。在 Java 中,您可以使用BigDecimal. 但是,我首先要弄清楚你是否真的需要这个精确的浮点数。

于 2012-06-24T08:28:48.800 回答