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;
}
À 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.
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.
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