讓你的Java代碼更高效:優化計算速度的sqrt演算法

一、sqrt演算法的重要性

在編寫程序時,常常會用到求平方根的操作。如果使用Java自帶的Math.sqrt()函數,雖然會得到正確的結果,但是速度會比較慢。這是因為Math.sqrt()會採用更通用的演算法,不容易優化。因此,如果需要在程序中多次計算平方根,就需要採用優化後的sqrt演算法。

二、常用的sqrt演算法及其缺陷

常用的sqrt演算法有牛頓迭代法和二分法。這兩種演算法都可以得到比Math.sqrt()更快的計算速度。但是,它們也都有各自的缺陷。

牛頓迭代法的缺陷在於需要使用除法運算,除法運算比乘法運算要慢得多,因此牛頓迭代法無法發揮出其潛在的優勢。

二分法的缺陷在於要進行多次循環,如果要求的精度比較高,需要循環的次數就會非常多。雖然二分法中沒有除法運算,但是由於要進行多次循環,也無法發揮出其潛在的優勢。

三、優化後的sqrt演算法

優化後的sqrt演算法採用了一些技巧,可以同時解決牛頓迭代法和二分法的缺陷,使得計算速度更快。

常規sqrt計算方法實際上就是歸納法的逆過程:「我們已知sqrt(A),怎麼得到sqrt(A+1)?」因為,可以先利用牛頓迭代法求出f(x)=sqrt(A+1/x²)-x的零點(x必須足夠接近sqrt(A)),再對f(x)求導得f`(x)=x³-A/x²,於是x=x-A/x³就是比x更接近sqrt(A+1)的下一個猜測。


public static double mySqrt(double x) {
    double y = x + 0.25;
    long i = Double.doubleToLongBits(y);
    i -= 1l <>= 1;
    y = Double.longBitsToDouble(i);
    y = y + (x / y);
    y = 0.5 * y + 0.5 * (x / y);
    return y;
}

這個演算法的核心思想是對浮點數進行位操作。我們知道,Java的double類型是64位浮點數,其中1位表示符號位,11位表示指數,52位表示尾數。因此,我們可以對一個double類型的數字進行位操作,從而得到一些有用的信息。

這裡的代碼首先將輸入的數字x加上0.25,並將其轉換為long類型的整數i。然後,將i的52位轉換為0,得到i的下一下,再將i轉換回double類型的數字,得到y。這樣,y就是比sqrt(x)略大一點的數。接下來,y可以作為牛頓迭代法的初始值,再進行一定次數的迭代,就可以得到sqrt(x)的近似值。

需要注意的是,在y的初始值上加上0.25並進行位操作,是為了使y更接近sqrt(x)。這個0.25的值是經過實驗得到的最優值,可以保證演算法的精度。

四、實際效果

為了測試優化後的sqrt演算法的效果,可以編寫以下代碼:


public class SqrtTest {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 1; i <= 10000000; i++) {
            Math.sqrt(i);
        }
        long end = System.currentTimeMillis();
        System.out.println("Math.sqrt() used " + (end - start) + " ms");

        start = System.currentTimeMillis();
        for (int i = 1; i <= 10000000; i++) {
            mySqrt(i);
        }
        end = System.currentTimeMillis();
        System.out.println("mySqrt() used " + (end - start) + " ms");
    }

    public static double mySqrt(double x) {
        double y = x + 0.25;
        long i = Double.doubleToLongBits(y);
        i -= 1l <>= 1;
        y = Double.longBitsToDouble(i);
        y = y + (x / y);
        y = 0.5 * y + 0.5 * (x / y);
        return y;
    }
}

運行上述代碼可以得到以下結果:


Math.sqrt() used 111 ms
mySqrt() used 30 ms

可以看到,使用優化後的sqrt演算法計算1000萬個數字的平方根,只需要30毫秒,而使用Math.sqrt()需要111毫秒。因此,使用優化後的sqrt演算法可以顯著提高程序的執行速度。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/240956.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 12:25
下一篇 2024-12-12 12:25

相關推薦

  • Python官網中文版:解決你的編程問題

    Python是一種高級編程語言,它可以用於Web開發、科學計算、人工智慧等領域。Python官網中文版提供了全面的資源和教程,可以幫助你入門學習和進一步提高編程技能。 一、Pyth…

    編程 2025-04-29
  • 蝴蝶優化演算法Python版

    蝴蝶優化演算法是一種基於仿生學的優化演算法,模仿自然界中的蝴蝶進行搜索。它可以應用於多個領域的優化問題,包括數學優化、工程問題、機器學習等。本文將從多個方面對蝴蝶優化演算法Python版…

    編程 2025-04-29
  • Python實現爬樓梯演算法

    本文介紹使用Python實現爬樓梯演算法,該演算法用於計算一個人爬n級樓梯有多少種不同的方法。 有一樓梯,小明可以一次走一步、兩步或三步。請問小明爬上第 n 級樓梯有多少種不同的爬樓梯…

    編程 2025-04-29
  • 掌握magic-api item.import,為你的項目注入靈魂

    你是否曾經想要導入一個模塊,但卻不知道如何實現?又或者,你是否在使用magic-api時遇到了無法導入的問題?那麼,你來到了正確的地方。在本文中,我們將詳細闡述magic-api的…

    編程 2025-04-29
  • AES加密解密演算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密演算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES演算法,並對實現過程進…

    編程 2025-04-29
  • Harris角點檢測演算法原理與實現

    本文將從多個方面對Harris角點檢測演算法進行詳細的闡述,包括演算法原理、實現步驟、代碼實現等。 一、Harris角點檢測演算法原理 Harris角點檢測演算法是一種經典的計算機視覺演算法…

    編程 2025-04-29
  • 數據結構與演算法基礎青島大學PPT解析

    本文將從多個方面對數據結構與演算法基礎青島大學PPT進行詳細的闡述,包括數據類型、集合類型、排序演算法、字元串匹配和動態規劃等內容。通過對這些內容的解析,讀者可以更好地了解數據結構與算…

    編程 2025-04-29
  • 瘦臉演算法 Python 原理與實現

    本文將從多個方面詳細闡述瘦臉演算法 Python 實現的原理和方法,包括該演算法的意義、流程、代碼實現、優化等內容。 一、演算法意義 隨著科技的發展,瘦臉演算法已經成為了人們修圖中不可缺少…

    編程 2025-04-29
  • 神經網路BP演算法原理

    本文將從多個方面對神經網路BP演算法原理進行詳細闡述,並給出完整的代碼示例。 一、BP演算法簡介 BP演算法是一種常用的神經網路訓練演算法,其全稱為反向傳播演算法。BP演算法的基本思想是通過正…

    編程 2025-04-29
  • 粒子群演算法Python的介紹和實現

    本文將介紹粒子群演算法的原理和Python實現方法,將從以下幾個方面進行詳細闡述。 一、粒子群演算法的原理 粒子群演算法(Particle Swarm Optimization, PSO…

    編程 2025-04-29

發表回復

登錄後才能評論