有人知道这是否是Java库错误吗? [英] Does anyone know if this is a Java library bug?

查看:84
本文介绍了有人知道这是否是Java库错误吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

** This is a corrected post **

我正在使用BigDecimal进行一些非常复杂的数学计算,并且在数千次测试之一中遇到了错误.有人看到我做错了什么愚蠢的东西吗?我不这么认为.

I'm doing some very intricate math calculations using BigDecimal and ran into an error in ONE of several thousand tests. Does anyone see something stupid that I did wrong? I don't think so.

下面的输出(从原始帖子中更正)是计算得出的几条迹线之一.好像Java只是错误地仅 printing 非BigInteger变量,因为该函数有效-使用x,ix,y和iy.问题是:为什么x的值会从一张打印变为另一张? -似乎我不应该做.

The output below (corrected from original post) is one of several traces from the calculations. It seems as if Java simply is only printing the non-BigInteger variables incorrectly because the function works - using x,ix, y and iy. The question is: why would the value of x change from one print to the next? - it doesn't seem like something I should be able to do.

当我不小心使内部常数pi和e精确到1500个小数位时,发生了错误.在1000个地方,一切都很好,没有错误.

The error occurred when I accidentally made internal constants pi and e accurate to 1,500 decimal places. At 1,000 places, all was fine and no error.

转储中的值x恰好等于= 2 * PI,约为6.283185307179586476925286766559下面是代码段.

The value x in the dump is coincidentally = is 2*PI which is approx 6.283185307179586476925286766559 Below is the snippet.

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 ^ n的倍数,包括为简洁起见未显示的测试-我将其截断了便于阅读)

The output is: (only the last line and 2 up from it are correct. note that the wrong values are always a multiple of 2^n of the correct value, including tests not shown for brevity -- and I cut off at right for readability)

******  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

**我相信只是原始数据中的标签有误.

** I believe it was only the labels that were wrong in the original data.

推荐答案

跟进.我错了上面的答案"仅部分解决了测试程序中的问题.它在实际程序中不起作用.

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

我在使用toBigDecimal( )[针对该错误数据]:
x = new BigDecimal(x.toString());

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

Followup. I was incorrect. The above 'answer' only partly solved the problem in the test program. It did not work in the real program.

I realize this is quite involved, but I did find a fix that corrected the mysterious inconsistent outputs, and this should prove convincing:

I added the following line before using toBigDecimal() [for that wrong data]:
x = new BigDecimal( x.toString() );

I would suspect that some attribute of the BigDecimal has gotten corrupted. It was not the scale.

这篇关于有人知道这是否是Java库错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆