将浮点数舍入为2位小数的最佳做法是什么?

vgo*_*anz 103 java math android

我正在使用eclipse + Android SDK.

我需要将浮点值舍入为2位小数.我通常使用数学库使用下一个"技巧".

float accelerometerX = accelerometerX * 100;
    accelerometerX = round(accelerometerX);
    Log.d("Test","" + accelerometerX/100);
Run Code Online (Sandbox Code Playgroud)

但我觉得这不是最好的方法.

是否有图书馆可以进行这些类型的操作?

提前致谢.

Jav*_*ock 151

我在2年前使用Java中的统计数据,我仍然得到一个函数的代码,允许您将数字四舍五入到您想要的小数位数.现在你需要两个,但也许你想用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();
}
Run Code Online (Sandbox Code Playgroud)

您需要决定是否要向上或向下舍入.在我的示例代码中,我正在四处寻找.

希望能帮助到你.

编辑

如果你想在它们为零时保留小数位数(我想这只是为了向用户显示)你只需要将函数类型从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;
}
Run Code Online (Sandbox Code Playgroud)

然后以这种方式调用函数:

float x = 2.3f;
BigDecimal result;
result=round(x,2);
System.out.println(result);
Run Code Online (Sandbox Code Playgroud)

这将打印:

2.30
Run Code Online (Sandbox Code Playgroud)

  • 但是现在,如果第二个是0,浮点只显示1个小数.你知道如何显示总是符号和所有(2)小数?示例:2.1234 - > 2.12但2.1 - > 2.1但没有2.10 (2认同)
  • 我在我正在开发的Android游戏中实现了这一点,每次创建一个新的`BigDecimal`实例多次占我内存分配的99.9%,所以需要注意的事项.在我看来,@ Evan Stin的方法2是最好的答案,它更快,不会留下任何东西. (2认同)

Iva*_*tin 47

让我们测试3种方法:
1)

public static double round1(double value, int scale) {
    return Math.round(value * Math.pow(10, scale)) / Math.pow(10, scale);
}
Run Code Online (Sandbox Code Playgroud)

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

3)

public static float round3(float d, int decimalPlace) {
    return BigDecimal.valueOf(d).setScale(decimalPlace, BigDecimal.ROUND_HALF_UP).floatValue();
}
Run Code Online (Sandbox Code Playgroud)



数字是0.23453f
我们将测试每种方法100,000次迭代.

结果:
时间1 - 18 ms
时间2 - 1 ms
时间3 - 378 ms


在笔记本电脑上测试
Intel i3-3310M CPU 2.4GHz


Sha*_*dow 33

double roundTwoDecimals(double d) {
  DecimalFormat twoDForm = new DecimalFormat("#.##");
  return Double.valueOf(twoDForm.format(d));
}
Run Code Online (Sandbox Code Playgroud)

  • 我正在尝试使用float函数,但抛出异常 (2认同)
  • 这对我有用..你需要像这样改变**float roundTwoDecimals(float d){DecimalFormat twoDForm = new DecimalFormat("#.##"); return Float.valueOf(twoDForm.format(d)); }** (2认同)

Jas*_*key 14

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


man*_*nta 7

我试图支持@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;
}
Run Code Online (Sandbox Code Playgroud)

以下是我尝试过的测试用例.如果没有解决任何其他情况,请告诉我.

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