将浮点数舍入到2位小数的最佳做法是什么?
我正在使用eclipse + Android SDK。
我需要将浮点值舍入为2位小数。 我通常使用math库的下一个“技巧”。
float accelerometerX = accelerometerX * 100; accelerometerX = round(accelerometerX); Log.d("Test","" + accelerometerX/100);
但我觉得这不是最好的办法。
有没有图书馆做这些types的操作?
提前致谢。
我在2年前使用Java中的统计工作,而且我仍然得到了一个函数的代码,它允许您将数字四舍五入到所需的小数位数。 现在你需要两个,但也许你想用3来比较结果,这个function给你这个自由。
/** * 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(); }
你需要决定是否要舍入或舍弃。 在我的示例代码中,我四舍五入。
希望能帮助到你。
编辑
如果你想保留小数位数为零(我想这只是为了显示给用户),你只需要将函数types从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
我们来testing3种方法:
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
我们将testing每种方法100,000次迭代。
结果:
时间1 – 18毫秒
时间2 – 1毫秒
时间3 – 378毫秒
在笔记本电脑上testing
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的第二种方法的-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; }
下面是我试过的testing用例。 请让我知道,如果这不是处理任何其他情况。
@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); }
这是一个简单的单线解决scheme
((int) ((value + 0.005f) * 100)) / 100f
//by importing Decimal format we can do... import java.util.Scanner; import java.text.DecimalFormat; public class Average { public static void main(String[] args) { int sub1,sub2,sub3,total; Scanner in = new Scanner(System.in); System.out.print("Enter Subject 1 Marks : "); sub1 = in.nextInt(); System.out.print("Enter Subject 2 Marks : "); sub2 = in.nextInt(); System.out.print("Enter Subject 3 Marks : "); sub3 = in.nextInt(); total = sub1 + sub2 + sub3; System.out.println("Total Marks of Subjects = " + total); res = (float)total; average = res/3; System.out.println("Before Rounding Decimal.. Average = " +average +"%"); DecimalFormat df = new DecimalFormat("###.##"); System.out.println("After Rounding Decimal.. Average = " +df.format(average)+"%"); } } /* Output Enter Subject 1 Marks : 72 Enter Subject 2 Marks : 42 Enter Subject 3 Marks : 52 Total Marks of Subjects = 166 Before Rounding Decimal.. Average = 55.333332% After Rounding Decimal.. Average = 55.33% */ /* Output Enter Subject 1 Marks : 98 Enter Subject 2 Marks : 88 Enter Subject 3 Marks : 78 Total Marks of Subjects = 264 Before Rounding Decimal.. Average = 88.0% After Rounding Decimal.. Average = 88% */ /* You can Find Avrerage values in two ouputs before rounding average And After rounding Average..*/