recherche

Maison  >  Questions et réponses  >  le corps du texte

Windows - Aide sur les problèmes de fonctionnement de haute précision Java

Le projet de l'entreprise nécessite de nombreuses opérations de haute précision. Au début, nous avons utilisé des opérations de type double. Plus tard, nous avons constaté que la précision de certaines valeurs dépassait la plage idéale après avoir utilisé des opérations de type double. Nous avons donc utilisé BigDecimal pour calculer. Le problème est maintenant le fonctionnement de BigDecimal. L'efficacité est des dizaines de fois plus lente que le double. Si la quantité de données est importante, elle sera extrêmement lente. Existe-t-il une bonne solution ? Ce problème doit être résolu de toute urgence.

//相关性系数计算
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;
    }
typechotypecho2731 Il y a quelques jours930

répondre à tous(3)je répondrai

  • 怪我咯

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

    À l'exception de l'utilisation de C ou C++ pour effectuer des opérations de haute précision, il ne semble y avoir aucun moyen de prendre en compte à la fois les performances et la précision.

    répondre
    0
  • 扔个三星炸死你

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

    Il existe un cours intitulé « Méthodes informatiques » dans la majeure en informatique de l'université, qui explique spécifiquement comment minimiser les erreurs dans le processus de calcul avec une précision limitée. Si vous êtes intéressé, vous pouvez trouver du matériel pédagogique pertinent.

    répondre
    0
  • 欧阳克

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

    Plus tard, j'ai découvert que la précision de certaines valeurs après avoir utilisé des opérations de type double dépassait la plage idéale
    Est-elle dépassée ou non satisfaite ?

    Voici un morceau de code pour calculer les racines carrées. Je l'ai trouvé sur stackoverflow. Lorsqu'il est testé sur ma propre machine, il est environ dix fois plus rapide que celui que vous avez ci-dessus.
    Donc : premièrement, vous pouvez améliorer les performances grâce à des algorithmes améliorés. Deuxièmement, le meilleur moyen est de trouver des bibliothèques existantes et de les utiliser directement : comme celle répertoriée ci-dessus

    .
    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());
    }

    répondre
    0
  • Annulerrépondre