Heim  >  Fragen und Antworten  >  Hauptteil

Windows – Hilfe bei Problemen mit der Java-Hochpräzisionsbedienung

Das Projekt des Unternehmens erfordert viele hochpräzise Operationen. Später stellten wir fest, dass die Genauigkeit einiger Werte nach der Verwendung von Doppeltypoperationen den idealen Bereich überschritt, und verwendeten daher BigDecimal zur Berechnung Das Problem ist nun, dass die Leistung von BigDecimal um ein Vielfaches langsamer ist. Wenn die Datenmenge groß ist, ist sie extrem langsam. Gibt es eine gute Lösung? Dieses Problem muss dringend gelöst werden.

//相关性系数计算
public BigDecimal getRelativityTool_bydim(RelativityTool u) {
        BigDecimal sim = new BigDecimal("0"); //最后的皮尔逊相关度系数

        BigDecimal common_items_len = new BigDecimal(this.rating_map_list.size()); //操作数的个数

        BigDecimal this_sum = new BigDecimal("0"); //第一个相关数的和

        BigDecimal u_sum = new BigDecimal("0"); //第二个相关数的和

        BigDecimal this_sum_sq = new BigDecimal("0"); //第一个相关数的平方和

        BigDecimal u_sum_sq = new BigDecimal("0"); //第二个相关数的平方和

        BigDecimal p_sum = new BigDecimal("0"); //两个相关数乘积的和

        for (int i = 0; i < this.rating_map_list.size(); i++) {
            BigDecimal this_grade = this.rating_map_list.get(i);
            BigDecimal u_grade = u.rating_map_list.get(i);
            //评分求和                     //平方和                     //乘积和

            this_sum = this_sum.add(this_grade);
            u_sum = u_sum.add(u_grade);
            this_sum_sq = this_sum_sq.add(this_grade.pow(2));
            u_sum_sq = u_sum_sq.add(u_grade.pow(2));
            p_sum = p_sum.add(this_grade.multiply(u_grade));
        }
        BigDecimal num = common_items_len.multiply(p_sum).subtract(this_sum.multiply(u_sum));
        BigDecimal den = sqrt(common_items_len.multiply(this_sum_sq).subtract(this_sum.pow(2)).multiply(common_items_len.multiply(u_sum_sq).subtract(u_sum.pow(2))));
        if (den.compareTo(new BigDecimal("0")) == 0) {
            sim = new BigDecimal("1");
        } else {
            sim = num.pide(den,5, BigDecimal.ROUND_HALF_UP);
        }
        return sim;
    }
    //大数字开方
    public static BigDecimal sqrt(BigDecimal x) {
        BigDecimal n1 = BigDecimal.ONE;
        BigDecimal ans = BigDecimal.ZERO;
        while ((n1.multiply(n1).subtract(x)).abs().compareTo(BigDecimal.valueOf(0.001)) == 1) {
            BigDecimal s1 = x.pide(n1, 2000, BigDecimal.ROUND_HALF_UP);
            BigDecimal s2 = n1.add(s1);
            n1 = s2.pide(BigDecimal.valueOf(2), 2000, BigDecimal.ROUND_HALF_UP);

        }
        ans = n1;
        BigDecimal rt = new BigDecimal(ans.toString().split("\.")[0]);
        return rt;
    }
typechotypecho2669 Tage vor868

Antworte allen(3)Ich werde antworten

  • 怪我咯

    怪我咯2017-06-28 09:24:10

    除了使用C或者C++来做高精度运算之外,好像没有什么办法可以同时兼顾性能和精度了。

    Antwort
    0
  • 扔个三星炸死你

    扔个三星炸死你2017-06-28 09:24:10

    大学计算机专业有门课程叫“计算方法”,专门探讨如何在精度有限的计算过程中保持误差最小化。楼主有兴趣的话可以找下相关教材。

    Antwort
    0
  • 欧阳克

    欧阳克2017-06-28 09:24:10

    后来发现用double类型运算后有些值的精确度超过了理想范围
    是超过还是满足不了?

    这里有一段计算平方根的代码,我从stackoverflow上找到的,在我自己的机子测试要比你上面那个快十倍左右。
    所以: 一则你可以通过改进的算法来提高性能,其二,最好的办法找一些已有的library来直接用:例如这个上面列的

    public void test_sqrt() {
        BigDecimal x = BigDecimal.valueOf(Long.MAX_VALUE);
        BigDecimal x0 = BigDecimal.ZERO;
        BigDecimal x2 = new BigDecimal(2);
        BigDecimal x1 = new BigDecimal(Math.sqrt(x.doubleValue()));
        while (!x0.equals(x1)) {
            x0 = x1;
            x1 = x.pide(x0, 2000, BigDecimal.ROUND_HALF_UP);
            x1 = x1.add(x0);
            x1 = x1.pide(x2, 2000, BigDecimal.ROUND_HALF_UP);
        }
        assertEquals(3037000499L, x1.longValue());
    }

    Antwort
    0
  • StornierenAntwort