我怎样才能修复这个可怜的BigDecimal四舍五入?

时间:2013-07-21 13:43:20

标签: java rounding bigdecimal

我在java中舍入BigDecimals时遇到了一些麻烦。 我试图将一个值从英尺转换为英寸,反之亦然,这就是我所拥有的:

//To convert from ft to in;
//...
BigDecimal CINCH = new BigDecimal("12");
Inch.setText(CINCH.multiply(VFEET).toString()); //VFEET is the user input

//To convert from in to ft
//...
BigDecimal CFEET = new BigDecimal("12"); //Initially I multiplied the input with 0.0833333333
Feet.setText(VINCH.divide(CFEET, 7, RoundingMode.HALF_UP).toString());  //VINCH is the user input

如果我尝试将1英尺转换为英寸,则返回预期值(12)。 如果我尝试将12英寸转换为英尺,它会返回预期值(1),但会有7个十进制情况,就像我预期的那样。

如果我将1英寸转换为英尺,则返回0.08333333,如果我将此值从英尺转换为英寸,则应该返回1,而是返回0.9999996。 如果我将2英寸转换为英尺,则返回0.1666667,如果我将此值从ft转换为in,则返回2.0000004

我该如何解决这个问题? (我知道我可以用双打来做这个,这是我的第一个计划,但我遇到了准确性问题(比这个更大))

1 个答案:

答案 0 :(得分:0)

但是,选择要用于表示的数据类型应该反映要解决的基本问题。通常,对于测量,您将使用双精度,因为测量的精度通常小于表示的精度。在这种情况下,表示中的错误不太重要。通常,您还将处理尺度相似的测量值,其中两个值之间的差异不接近表示的精度。在您的情况下,您似乎需要比双精度表示更高的精度,但不希望数字显示为小数所允许的精度。

一种可能的解决方案是在内部保持值的精度高于显示的值。无论类型如何,这都适用,但使用decimal的示例很容易证明。例如(在C#中)

decimal f = 1m;
decimal i = f / 12m;

Console.WriteLine("{0} {1} {2} {3}", f, i, i * 12m, Math.Round(i * 12m, 7));

生成以下输出,您可以通过显示更少的数字来查看 预期答案

1 0.0833333333333333333333333333 0.9999999999999999999999999996 1.0000000

我的建议是以更高的精度进行算术运算,并以更低的精度进行显示。在您的情况下,您正在以7的比例进行算术运算,因此您可能希望在输出中出现最多6位数的精度,或者相反地将比例设置得更高,这样您就可以显示与测量结果相同的精确位数。 / p>

您可能还会发现这有用,Scale() of Divide method in BigDecimal