Android 中的浮动增量问题

Sco*_*ion 0 java floating-point android increment floating-accuracy

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

float kmVal = 0.0f;    
EditText kms = (EditText) findViewById(R.id.km);
kmVal = Float.valueOf(kms.getText().toString()); 
Run Code Online (Sandbox Code Playgroud)

单击按钮时,我正在增加值。

kmVal += 0.1;
kms.setText(String.valueOf(kmVal));
Run Code Online (Sandbox Code Playgroud)

日志 :-

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
Run Code Online (Sandbox Code Playgroud)

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

谢谢

Kaz*_*ara 5

这是因为浮点型数字是如何表示的。从JLS

任何浮点值集的有限非零值都可以表示为 s·m·2(e - N + 1),其中 s 为 +1 或 -1,m 为小于 2N 的正整数,并且e 是介于 Emin = -(2K-1-2) 和 Emax = 2K-1-1 之间的整数,其中 N 和 K 是取决于值集的参数。

因此,浮点值不能准确地表示以 10 为底的实数。虽然您可能会得到初始值0.1,但实际发生的是您得到的0.0999999999999999996是变成了0.1. 但是当您继续对其进行操作时,它会不断失去精度。

阅读这个这个了解更多。

为了精确使用BigDecimal

BigDecimal test = new BigDecimal("0.1");
test = test.add(new BigDecimal("0.1"));
System.out.println(test);
Run Code Online (Sandbox Code Playgroud)