截断的双倍在java中的for循环中获取长小数

时间:2012-02-14 06:51:56

标签: java

我有两个双精度值被截断为两个小数点。每一个都代表弧度圆上的一个点,它们要么递增或递减0.01,直到它们找到目标值。这是代码:

    BigDecimal negPath = new BigDecimal(roundAndConvert(pendA.getTheta()));
    BigDecimal posPath = new BigDecimal(roundAndConvert(pendA.getTheta()));
    BigDecimal target = new BigDecimal(roundAndConvert(pendB.getTheta()));
    for (negPath = negPath; ((negPath.doubleValue() > -0.01) && (!negPath.equals(target))); negPath = negPath.subtract(new BigDecimal(0.01))) {}
    for (posPath = posPath; ((posPath.doubleValue() < 6.29) && (!posPath.equals(target))); posPath = posPath.add(new BigDecimal(0.01))) {}

//here's the method that rounds the values

public double roundAndConvert(double value)
{
        double holder = (int)(value*100) / 100.0;
        if (holder < 0)
        {
            while (holder < -6.28) {holder += 6.28;}
            holder += 6.28;
        }
        else
        {
            while (holder > 6.28) {holder -= 6.28;}
        }
        return holder;
}

我遇到的问题是两个Path值都返回带有长小数的双精度数,如下所示:

pos = 6.299999999999944
neg = -0.01999999999996656

它们返回的值在for循环之前不是这样的,所以我认为它与增量/减量有关。

编辑:尝试用BigDecimals替换双打,但现在程序在for循环中冻结。我看到了PathCache的Path值,它们仍然有很长的小数。

编辑:编码的另一个变化,这次使用for循环中的所有BigDecimal个对象和equals,但我仍然得到很长的小数。

编辑:最后使用了显示的编码。接受的回答者解释了我做错了什么。这是有效的代码:

    for (negPath = negPath; ((negPath.doubleValue() > -0.01) && (!negPath.equals(new BigDecimal((int)(target.doubleValue()*100)/100.0)))); negPath = negPath.subtract(new BigDecimal(0.01))) 
    {
        negPath = new BigDecimal((int)(negPath.doubleValue()*100)/100.0);
    }
    for (posPath = posPath; ((posPath.doubleValue() < 6.29) && (!posPath.equals(new BigDecimal((int)(target.doubleValue()*100)/100.0)))); posPath = posPath.add(new BigDecimal(0.01))) 
    {
        negPath = new BigDecimal((int)(negPath.doubleValue()*100)/100.0);
    }

2 个答案:

答案 0 :(得分:3)

您的代码:

for (negPath = negPath; 
      ((negPath.doubleValue() > -0.01) && (negPath.doubleValue() != target));
      negPath.subtract(new BigDecimal(0.01))) 
{}

我在这里看到两个错误。第一:

negPath.subtract(new BigDecimal(0.01))

应该是

negPath = negPath.subtract(new BigDecimal(0.01))

因为BigDecimal是不可变的 - 对它们的每个操作只会创建一个新的操作。这可能就是为什么你的循环现在永远不会终止的原因 - 因为状态在每个循环中都不会改变。

第二

(negPath.doubleValue() != target)

比较那种方式的双打是禁忌,因为中间舍入错误肯定会发生,然后这部分条件永远不会成立。

理由:请阅读一些关于浮点计算的基本文档 - 浮点数不仅仅是数学中的数字,还必须小心对待它们。

答案 1 :(得分:0)

使用BigDecimal而不是double。