奇怪的双字符串转换

Jui*_*iCe -1 double android

我正在使用以下代码在我的一个活动中填充Spinner ...

    for( double i = 0; i < 10 ; i+=0.1 ) {
        rVoltsList.add( Double.toString( i ) );
    }
    Spinner rVoltsSpinner = (Spinner) findViewById( R.id.recloseVoltsSpinner );
    ArrayAdapter<String> rVoltsAdapter = new ArrayAdapter<String>( this, android.R.layout.simple_spinner_item, rVoltsList );
    rVoltsSpinner.setAdapter( rVoltsAdapter );
Run Code Online (Sandbox Code Playgroud)

我假设这会给我一个如下列表:0.0,0.1,0.2,0.3,0.4等.但是,这是我运行程序时列表的样子:

0.0
0.1
0.2
0.30000000000000000000000004
0.4
0.5
0.6
0.7
0.79999999999999999999
0.89999999999999999999
0.99999999999999999999
1.09999999999999999999
1.2
1.3
and this goes on until 9.99999999999999999998
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Ted*_*opp 5

用这个:

rVoltsList.add( String.format("%.1f", i) );
Run Code Online (Sandbox Code Playgroud)

问题是Double.toString(i)不会圆.

奇怪的值是由于0.1(基数10)double在Java 中没有精确表示的事实,因此每次将它添加到循环变量时,您添加的内容与您的想法有所不同(如果您请原谅双关语.

同样的舍入问题表明你不应该使用a double作为循环变量.你不太可能完全达到你的循环限制.我会按如下方式重写你的循环:

for( int i = 0; i < 100 ; ++i ) {
    rVoltsList.add( String.format("%.1f", i / 10.0) );
}
Run Code Online (Sandbox Code Playgroud)

  • @JuiCe - 问题是双打算法通常不准确.特别地,(基数10)值0.1不具有二进制的精确表示.因此,总和的最后一位或两位将关闭.对于一个数字加0.1的次数越多,这种舍入误差通常越差. (2认同)