有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何修复这个糟糕的大十进制舍入?

我在java中舍入大小数时遇到了一些问题。 我试图将一个值从英尺转换为英寸,反之亦然,这就是我得到的:

//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.999996。 如果将2英寸转换为英尺,则返回0.1666667;如果将此值从英尺转换为英寸,则返回2.0000004

我该怎么解决这个问题?(我知道我可以用双打来做到这一点,这是我的第一个计划,但我遇到了一个精度问题(比这个问题更大))


共 (1) 个答案

  1. # 1 楼答案

    不过,选择用于表示的数据类型应该反映出需要解决的根本问题。通常,对于测量,您会使用双精度,因为测量的精度通常低于表示的精度。在这种情况下,表示中的错误不太显著。一般来说,你也会处理在比例上相似的测量值,其中两个值之间的差异不接近表示的精度。在您的情况下,似乎需要比双精度表示的精度更高的精度,但不希望数字显示到小数允许的精度

    一种可能的解决方案是在内部以比显示更高的精度保留值。无论是哪种类型,这都适用,但可以通过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位精度,或者反过来将比例设置得更高,这样你就可以根据测量结果显示尽可能多的精度数字

    你可能也会发现这很有用,Scale() of Divide method in BigDecimal