Eclipse + Android SDKを使用しています。
Float値を小数点以下2桁に丸める必要があります。私は通常、Mathライブラリを使用して次の「トリック」を使用します。
float accelerometerX = accelerometerX * 100;
accelerometerX = round(accelerometerX);
Log.d("Test","" + accelerometerX/100);
しかし、それが最善の方法ではないと感じています。
これらのタイプの操作を実行するライブラリはありますか?
前もって感謝します。
私は2年前にJavaで統計を扱っていましたが、数値を必要な小数の数に丸めることができる関数のコードがまだありました。 2つが必要になりましたが、結果を比較するために3で試してみたいと思うかもしれません。この関数はこの自由を与えます。
/**
* Round to certain number of decimals
*
* @param d
* @param decimalPlace
* @return
*/
public static float round(float d, int decimalPlace) {
BigDecimal bd = new BigDecimal(Float.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.floatValue();
}
切り上げるか切り捨てるかを決める必要があります。サンプルコードでは、切り上げています。
それが役に立てば幸い。
編集
小数点以下の桁数がゼロの場合(ユーザーに表示するためだけだと思います)、小数点以下の桁数を保持する場合は、次のように関数の型をfloatからBigDecimalに変更するだけです。
public static BigDecimal round(float d, int decimalPlace) {
BigDecimal bd = new BigDecimal(Float.toString(d));
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd;
}
そして、この方法で関数を呼び出します:
float x = 2.3f;
BigDecimal result;
result=round(x,2);
System.out.println(result);
これは印刷されます:
2.30
つのメソッドをテストしましょう:
1)
public static double round1(double value, int scale) {
return Math.round(value * Math.pow(10, scale)) / Math.pow(10, scale);
}
2)
public static float round2(float number, int scale) {
int pow = 10;
for (int i = 1; i < scale; i++)
pow *= 10;
float tmp = number * pow;
return ( (float) ( (int) ((tmp - (int) tmp) >= 0.5f ? tmp + 1 : tmp) ) ) / pow;
}
3)
public static float round3(float d, int decimalPlace) {
return BigDecimal.valueOf(d).setScale(decimalPlace, BigDecimal.ROUND_HALF_UP).floatValue();
}
数値は0.23453fです
各メソッドで100,000回の反復をテストします。
結果:
時間1-18ミリ秒
時間2-1 ms
時間3-378ミリ秒
ラップトップでテスト済み
Intel i3-3310M CPU 2.4GHz
double roundTwoDecimals(double d) {
DecimalFormat twoDForm = new DecimalFormat("#.##");
return Double.valueOf(twoDForm.format(d));
}
@Jav_Rockに比べて短い実装を示します
/**
* Round to certain number of decimals
*
* @param d
* @param decimalPlace the numbers of decimals
* @return
*/
public static float round(float d, int decimalPlace) {
return BigDecimal.valueOf(d).setScale(decimalPlace,BigDecimal.ROUND_HALF_UP).floatValue();
}
System.out.println(round(2.345f,2));//two decimal digits, //2.35
@Ivan Stinの優れた2番目の方法の-ve値をサポートしようとしました。 (主な功績は彼の方法で@Ivan Stinに送られます)
public static float round(float value, int scale) {
int pow = 10;
for (int i = 1; i < scale; i++) {
pow *= 10;
}
float tmp = value * pow;
float tmpSub = tmp - (int) tmp;
return ( (float) ( (int) (
value >= 0
? (tmpSub >= 0.5f ? tmp + 1 : tmp)
: (tmpSub >= -0.5f ? tmp : tmp - 1)
) ) ) / pow;
// Below will only handles +ve values
// return ( (float) ( (int) ((tmp - (int) tmp) >= 0.5f ? tmp + 1 : tmp) ) ) / pow;
}
以下は私が試したテストケースです。これが他のケースに対応していない場合はお知らせください。
@Test
public void testFloatRound() {
// +ve values
Assert.assertEquals(0F, NumberUtils.round(0F), 0);
Assert.assertEquals(1F, NumberUtils.round(1F), 0);
Assert.assertEquals(23.46F, NumberUtils.round(23.4567F), 0);
Assert.assertEquals(23.45F, NumberUtils.round(23.4547F), 0D);
Assert.assertEquals(1.00F, NumberUtils.round(0.49999999999999994F + 0.5F), 0);
Assert.assertEquals(123.12F, NumberUtils.round(123.123F), 0);
Assert.assertEquals(0.12F, NumberUtils.round(0.123F), 0);
Assert.assertEquals(0.55F, NumberUtils.round(0.55F), 0);
Assert.assertEquals(0.55F, NumberUtils.round(0.554F), 0);
Assert.assertEquals(0.56F, NumberUtils.round(0.556F), 0);
Assert.assertEquals(123.13F, NumberUtils.round(123.126F), 0);
Assert.assertEquals(123.15F, NumberUtils.round(123.15F), 0);
Assert.assertEquals(123.17F, NumberUtils.round(123.1666F), 0);
Assert.assertEquals(123.46F, NumberUtils.round(123.4567F), 0);
Assert.assertEquals(123.87F, NumberUtils.round(123.8711F), 0);
Assert.assertEquals(123.15F, NumberUtils.round(123.15123F), 0);
Assert.assertEquals(123.89F, NumberUtils.round(123.8909F), 0);
Assert.assertEquals(124.00F, NumberUtils.round(123.9999F), 0);
Assert.assertEquals(123.70F, NumberUtils.round(123.7F), 0);
Assert.assertEquals(123.56F, NumberUtils.round(123.555F), 0);
Assert.assertEquals(123.00F, NumberUtils.round(123.00F), 0);
Assert.assertEquals(123.50F, NumberUtils.round(123.50F), 0);
Assert.assertEquals(123.93F, NumberUtils.round(123.93F), 0);
Assert.assertEquals(123.93F, NumberUtils.round(123.9312F), 0);
Assert.assertEquals(123.94F, NumberUtils.round(123.9351F), 0);
Assert.assertEquals(123.94F, NumberUtils.round(123.9350F), 0);
Assert.assertEquals(123.94F, NumberUtils.round(123.93501F), 0);
Assert.assertEquals(99.99F, NumberUtils.round(99.99F), 0);
Assert.assertEquals(100.00F, NumberUtils.round(99.999F), 0);
Assert.assertEquals(100.00F, NumberUtils.round(99.9999F), 0);
// -ve values
Assert.assertEquals(-123.94F, NumberUtils.round(-123.93501F), 0);
Assert.assertEquals(-123.00F, NumberUtils.round(-123.001F), 0);
Assert.assertEquals(-0.94F, NumberUtils.round(-0.93501F), 0);
Assert.assertEquals(-1F, NumberUtils.round(-1F), 0);
Assert.assertEquals(-0.50F, NumberUtils.round(-0.50F), 0);
Assert.assertEquals(-0.55F, NumberUtils.round(-0.55F), 0);
Assert.assertEquals(-0.55F, NumberUtils.round(-0.554F), 0);
Assert.assertEquals(-0.56F, NumberUtils.round(-0.556F), 0);
Assert.assertEquals(-0.12F, NumberUtils.round(-0.1234F), 0);
Assert.assertEquals(-0.12F, NumberUtils.round(-0.123456789F), 0);
Assert.assertEquals(-0.13F, NumberUtils.round(-0.129F), 0);
Assert.assertEquals(-99.99F, NumberUtils.round(-99.99F), 0);
Assert.assertEquals(-100.00F, NumberUtils.round(-99.999F), 0);
Assert.assertEquals(-100.00F, NumberUtils.round(-99.9999F), 0);
}
これがシンプルな1行のソリューションです
((int) ((value + 0.005f) * 100)) / 100f