【问题标题】:Does anyone know if this is a Java library bug?有谁知道这是否是 Java 库错误?
【发布时间】:2015-05-06 21:09:39
【问题描述】:

** 这是一个更正的帖子**

我正在使用 BigDecimal 进行一些非常复杂的数学计算,并在几千次测试中遇到了一个错误。有没有人看到我做错了什么愚蠢的事情?我不这么认为。

下面的输出(从原始帖子更正)是计算中的几个痕迹之一。似乎 Java 只是错误地打印非 BigInteger 变量,因为该函数有效 - 使用 x、ix、y 和 iy。问题是:为什么 x 的值会从一个打印到下一个? - 这似乎不是我应该做的事情。

当我不小心将内部常量 pi 和 e 精确到小数点后 1,500 位时发生了错误。在 1000 个地方,一切都很好,没有错误。

转储中的值 x 巧合 = 是 2*PI,大约是 6.283185307179586476925286766559 下面是 sn-p。

public  static  int     cmp(BigDecimal x, BigDecimal y, int places)
{
    BigInteger ix = x.movePointRight(places).toBigInteger();

    String sInt = ix.toString();
    BigDecimal shiftX = x.movePointRight(places);
    String sx = x.movePointRight(places).toString();
    int dot = sx.indexOf('.');          // making the shifted x
    if (dot > 0)                        //  string into an integer string
        sx = sx.substring(0,dot);       //   just for comparison
    if ( !sx.equals(sInt) )
    {
        System.out.println("******  cmp(): Mismatch between X values.    dec places = " + places);
        System.out.println("x                   = " + x);
        System.out.println("x.toString()        = " + x.toString());
        System.out.println("x.toPlain()         = " + x.toPlainString());

        System.out.println("x.right() #1        = " + x.movePointRight(places));
        System.out.println("x.right() #2        = " + shiftX);
        System.out.println("x.right() #3        = " + sx);

        String shiftXStr = x.movePointRight(places).toString();
        System.out.println("x.right().str() #1  = " + x.movePointRight(places).toString());
        System.out.println("x.right().str() #2  = " + shiftXStr);

        String shiftXPlain = x.movePointRight(places).toPlainString();
        System.out.println("x.right().plain() 1 = " + x.movePointRight(places).toPlainString());
        System.out.println("x.right().plain() 2 = " + shiftXPlain);

        System.out.println("x.toBigInt()        = " + x.toBigInteger());

        System.out.println("BigInt(x) #1        = " + x.movePointRight(places).toBigInteger());
        System.out.println("BigInt(x) #2        = " + ix);

        System.out.println("BigInt(x).str() 1   = " + x.movePointRight(places).toBigInteger().toString());
        System.out.println("BigInt(x).str() 2   = " + sInt);
    }

输出是:(只有最后一行和它上面的 2 行是正确的。请注意,错误的值始终是正确值的 2^n 的倍数,包括为简洁起见未显示的测试——我切断了右侧为便于阅读)

******  cmp(): Mismatch between X values.    dec places = 595
x                   = 205887.41614566068967588779676660550101874569
x.toString()        = 205887.41614566068967588779676660550101874569
x.toPlain()         = 205887.41614566068967588779676660550101874569
x.right() #1        = 205887416145660689675887796766605501018745693
x.right() #2        = 205887416145660689675887796766605501018745693
x.right() #3        = 205887416145660689675887796766605501018745693
x.right().str() #1  = 205887416145660689675887796766605501018745693
x.right().str() #2  = 205887416145660689675887796766605501018745693
x.right().plain() 1 = 205887416145660689675887796766605501018745693
x.right().plain() 2 = 205887416145660689675887796766605501018745693
x.toBigInt()        = 205887
BigInt(x) #1        = 205887416145660689675887796766605501018745693
BigInt(x) #2        = 628318530717958647692528676655900576839433879
BigInt(x).str() 1   = 205887416145660689675887796766605501018745693
BigInt(x).str() 2   = 628318530717958647692528676655900576839433879

** 我相信只是原始数据中的标签有问题。

【问题讨论】:

  • 该代码正确吗? x.toBigInt() 和 BigInt() 输出看起来是一样的。
  • 你找到这两个字符串的不同之处了吗?
  • 旁注:System.out.println("x = " + x);System.out.println("x.toString() = " + x.toString()); 完全相同(当然标签除外)
  • 我在获得 Java 经验时学到的经验法则:总是你的错。但实际上:在 BigDecimal 如此广泛使用的类中很难轻易找到错误。我试图找出您的代码有什么问题,但我无法完全理解问题所在。
  • 哎呀...我很抱歉,我没有看到我的剪切/粘贴错误 - 不,输出与代码不匹配。我将重新运行整个测试并修复帖子。但是问题还是有点清楚的..

标签: java biginteger bigdecimal


【解决方案1】:

这可能属于这里。

我必须感谢所有查看此问题的人。

我可能偶然发现了答案,很高兴这是我的问题。我在我的测试程序中发现了一个错误并修复它解决了上面的问题。我真正追求的问题也消失了,但由于某种原因,诊断跟踪仍然打印出与上述不一致的值,这仍然是一个谜。

整个问题似乎与继承类的静态初始化没有按照我想的顺序发生有关 - 在一种情况下。

【讨论】:

    【解决方案2】:

    跟进。我错了。上面的“答案”只是部分解决了测试程序中的问题。它在实际程序中不起作用。

    我意识到这很复杂,但我确实找到了一个修复程序来纠正神秘的不一致输出,这应该证明是令人信服的:

    我在使用 toBigDecimal() [针对错误数据] 之前添加了以下行:
    x = new BigDecimal( x.toString() );

    我怀疑 BigDecimal 的某些属性已损坏。这不是规模。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-21
      • 2021-07-20
      • 1970-01-01
      • 1970-01-01
      • 2018-08-09
      • 1970-01-01
      • 2018-01-16
      • 1970-01-01
      相关资源
      最近更新 更多