Windows - Bantuan dengan masalah operasi berketepatan tinggi Java
typecho
typecho 2017-06-28 09:22:10
0
3
947

Projek syarikat memerlukan banyak operasi berketepatan tinggi Pada mulanya, kami menggunakan operasi jenis berganda Kemudian, kami mendapati bahawa ketepatan beberapa nilai melebihi julat ideal selepas menggunakan operasi jenis berganda, jadi kami menggunakan BigDecimal untuk mengira. . Masalahnya sekarang ialah operasi BigDecimal. Adakah terdapat sebarang penyelesaian yang baik? Masalah ini perlu diselesaikan dengan segera.

//相关性系数计算
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;
    }
typecho
typecho

Following the voice in heart.

membalas semua(3)
刘奇

Kecuali untuk menggunakan C atau C++ untuk melakukan operasi ketepatan tinggi, nampaknya tiada cara untuk mengambil kira prestasi dan ketepatan.

扔个三星炸死你

Terdapat kursus yang dipanggil "Kaedah Pengiraan" dalam jurusan komputer universiti, yang membincangkan secara khusus bagaimana untuk meminimumkan ralat dalam proses pengiraan dengan ketepatan yang terhad. Jika anda berminat, anda boleh mencari bahan pengajaran yang berkaitan.

学霸

Kemudian saya mendapati bahawa ketepatan beberapa nilai ​​selepas menggunakan operasi jenis dua kali melebihi julat ideal
Adakah ia melebihi atau tidak berpuas hati?

Berikut ialah sekeping kod untuk mengira punca kuasa dua yang saya temui pada stackoverflow Apabila diuji pada mesin saya sendiri, ia adalah kira-kira sepuluh kali lebih cepat daripada yang anda miliki di atas.
Jadi: Pertama, anda boleh meningkatkan prestasi melalui algoritma yang dipertingkatkan. Kedua, cara terbaik ialah mencari beberapa perpustakaan sedia ada dan menggunakannya secara langsung: seperti yang disenaraikan di atas

.
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());
}
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan