3

我正在写一个函数轮:静态浮点轮(浮点数,精度){}

该函数应该像这样工作:round(12.3456f, 3) = 12.345

我对函数的定义是这样的:

public static float round(float value, int precision) {
float result;
if(precision <= 0){
    throw new RuntimeException("Precision can not be zero or less");
}

int number = (int) power(10,precision);
value = value * number;
result = (float)Math.round(value)/number;

return result;
} 

但问题是,我的这个函数的单元测试用例没有通过,

 public void mathTestNew() {
    assertEquals("MathTest",12.341,OOTBFunctions.round(12.3416f,3));
 }

结果是 junit.framework.AssertionFailedError: MathTest expected:<12.341> but was:<12.342>

我不确定如何克服这个错误。我不确定 BigDecimal 是否会在这方面帮助我。

4

5 回答 5

4

舍入通常发生在最接近的整数。所以12.3416正确四舍五入12.342

如果您想要您似乎要求的舍入行为(数字向下舍入到负无穷大),那么您应该使用Math.floor(x)而不是 Math.round(x)

还要小心舍入浮点数/双精度数,因为它们都存在数值不准确的问题。如果你真的想要小数位的高精度,你可能会更好地使用BigDecimal代替。

于 2012-05-29T23:42:30.647 回答
3

Math.round是“四舍五入”。你可能想要Math.floor.

于 2012-05-29T23:40:52.283 回答
2

如果您确实想使用BigDecimal

public static float round(float value, int precision) {
    if (precision <= 0) {
        throw new IllegalArgumentException("Precision cannot be zero or less.");
    }
    BigDecimal decimal = BigDecimal.valueOf(value);
    return decimal.setScale(precision, RoundingMode.FLOOR).floatValue();
}

BigDecimal从到转换时可能会失去准确性float,因此如果必须准确,请不要转换;将值保持为 a BigDecimal

正如其他答案中提到的,float是一个以 10 为底的数字的近似值。以下仅说明了这一点:

System.out.println(BigDecimal.valueOf(12.3416f)); // outputs 12.34160041809082
System.out.println(new BigDecimal("12.3416"));    // outputs 12.3416
于 2012-05-29T23:52:08.467 回答
1

12.3416四舍五入是12.342。你的问题就在于此。你可能想要Math.Floor。我建议不要不断增加,因为这会破坏数字。但是,按 10 并不会降低精度。

于 2012-05-29T23:41:01.713 回答
0

你不能写这样的方法。浮点数没有小数位,它有二进制位。因此,您不能四舍五入到指定的小数位数。如果您想要小数位,您必须使用十进制基数,即 BigDecimal 或 DecimalFormat。除了@ColeJohnson 指出的预期错误之外,您编写的代码在 90% 以上的情况下都会失败。

于 2012-05-29T23:42:03.843 回答