如何使用java語言求一個正整數的平方根?(不使用庫函數)

2021-01-11 愚公要移山1

今天的這篇文章是我在刷算法題的時候遇到的,最簡單的方法是直接調用java裡面的Sqrt函數,不過有時候題目中會要求我們不能使用庫函數,所以在這裡我們自己定義Sqrt方法。

最常見的思路有兩種,第一種是二分法,第二種是牛頓的微積分思想。沒錯,想當年大學時候學了很久很痛苦的微積分,被我第一次派上用場了。對於這兩種方法我們一個一個看。

一、二分法

二分法的思想很簡單,就是從0到N不斷地去縮小範圍來找一個一個滿足精度的最佳值。我們舉一個函數的例子:

這就是二分法的思想,求平方根也是,我們從0到value取出中間值,然後不斷地比較,假設value=10,查找區間為(0,10),這時候取(0,10)的中間值mid=5,mid*mid再和value比較之後,確定下一次查找的區間變為(0,5),依此類推。一直到滿足我們需要的精度即可。下面我們使用java代碼實現一下:

在這裡value就是我們要求的數字,t表示的是精度。這個方法在這,大家可以測試一遍。不過在這裡有一個小小的問題需要我們去注意:

如果我們對整數9取平方根,結果不是3,這裡有精度損失,損失的原因之一是和計算機有關的,因為計算機的底層其實只有0和1,所以會無限的接近,而不能精確表示。

以上就是二分法求解的思想,這個思想很簡單,不過實現的方法卻是有一點點麻煩。在這裡我們開始介紹第二種方法,那就是牛頓的微積分思想

二、牛頓迭代法

牛頓的微積分的思想就是無限接近,在這裡提一句,如果你是數學大佬就不要追究思想到底是啥了。對於求平方根來說,使用切線來無限逼近的方式有時候能起到意想不到的效果。

設r是f(x) = 0的根,選取x0作為r初始近似值,過點(x0,f(x0))做曲線y = f(x)的切線L,L的方程為y = f(x0)+f'(x0)(x-x0),求出L與x軸交點的橫坐標 x1 = x0-f(x0)/f'(x0),稱x1為r的一次近似值。過點(x1,f(x1))做曲線y = f(x)的切線,並求該切線與x軸交點的橫坐標 x2 = x1-f(x1)/f'(x1),稱x2為r的二次近似值。重複以上過程,得r的近似值序列,其中x(n+1)=x(n)-f(x(n))/f'(x(n)),稱為r得n+1次近似值,上式稱為牛頓迭代公式。

我們使用一張圖來演示一下:

這種方式也很好理解。所以我們直接來看實現:

上面的方法同樣可以表示。而且我們可以看到,牛頓的這個方法其實更加的簡單。而且精度也更好。

相關焦點

  • 單片機C語言實現求平方根算法
    C語言中要求平方根,可以在頭文件中加入#include <math.h>.然後調用sqrt(n);函數即可。但在單片機中調用此函數無疑會耗費大量資源和時間,是極不合適的。在此,總結下網上常見的四種單片機常用開方根算法:對於擁有專門的乘除法指令的單片機,可採用以下兩種方法:1、二分法對於一個非負數n,它的平方根不會小於大於(n/2+1)(謝謝@linzhi-cs提醒)。在[0, n/2+1]這個範圍內可以進行二分搜索,求出n的平方根。
  • 跟我學java編程—認識java的整數類型
    Java語言中,基本的整型數據類型有byte、short、int、long四種類型,用於需要不同存儲空間的數據使用。整型有正整數和負整數之分,在Java語言中,規定整型的最高位為符號位,最高位為「0」表示正數,最高位為「1」表示負數,其它位表示數值。因此整型類型的數據能夠表示的最小值為:-2n-1 —2n-1-1(n為該類型所佔存儲空間的二進位位數)。
  • excel怎麼計算平方根-記住簡單的收藏複雜的
    在excel中,有四百多個函數,如果再組合應用那就成千上萬個,具體多少別再糾結了,香哥只想表明一個問題,簡單的好記又常用的就記住,複雜的不常用的找到好的使用文章就收藏了,這樣才能提高工作效率。excel怎麼計算平方根,方法如下,一個函數解決問題。
  • 求2的平方根的三種方法
    的最大整數解,這是第二個準確數。我猜4已經很變態了,求2的平方根居然猜4,但速度還是超級快。缺點嘛……看不懂,真的看不懂。(呵呵)那個迭代公式是何方神聖?我把數學過程一寫您就明白了。對證明沒興趣的讀者可以跳過。
  • 51單片機整數二一十進位轉換的快速算法
    在單片機系統開發中,經常遇到整數二十進位轉換的問題,一般可以採用C語言中的標準函數sprintf()來實現;但由於該函數是通用格式輸出函數,代碼量大(超過l KB),用於整數二一十進位轉換的運算時間過妊(在12 MHz晶振頻率下超過l ms),這在計算密集(computation intensive)的應用中是一個影響系統性能的重要因素。
  • 十一個純粹數學函數的用法歸納
    本來我在這個平臺上不想寫過於單純數學的函數。但是由於涉及到平臺知識覆蓋面的問題,還是簡單地寫一些吧。這類函數是純粹的數學函數,很簡單,只是為了朋友們能在我的這個平臺上方便地找到使用方法。1. SIN 正弦函數用途:返回某一角度的正弦值。
  • R語言中因子的創建與使用
    因子在R語言中可以用來表示名義型變量或有序變量。名義變量一般表示類別,如性別,種族等等。有序變量是有一定排序順序的變量,如職稱,年級等等。在R語言中,名義變量和有序變量可以使用因子來表示。創建因子在R語言中可以使用factor()函數和gl()函數來創建因子變量。
  • C/C++語言中將一個正整數圓整為2的n次方的方法
    問題提出在數位訊號處理領域,常遇到需要將一個正整數向上圓整為2的n次方的數據的情況,如對採集到的時域信號做頻譜分析時,常要求數據點數必須滿足為2的n次方,滿足此種情況才可用傅立葉變換的基2快速算法,以達到較好的運算速度。
  • 一個方法快速求任意正數平方根
    其中,y為被開方數,a為整數,x的絕對值≤a。例如,2536可改寫成50²+36,2455可改寫成50²+(-45)。然後,利用以下不等式:a+(x/2a-1)≤√y≤a+(x/2a)(上一步求出的x為負數)a+(x/2a+1)≤√y≤a+(x/2a)(上一步求出的x為正數)例如,計算2536的平方根,則2536可改寫成50²+36,套用公式,a+(x/2a+1)=50.356,a+(x/2a)=50.36,因此可以粗略認為2536的平方根在50.356和50.36
  • Python如何判斷一個正整數是否是素數?
    而一個數的約數必然是不超過該數的,加上素數必需是只有1和本身是其約數的條件。於是,我們可以通過枚舉小於該數,並且大於1的整數,來判斷該數是否是素數。假設有一個正整數a,則其可以被寫成任意兩個正整數之積,即a = p * q。假設p < q,那么正整數p和q都是a的約數。注意到,如果我們知道p是a的約數,那麼可以通過q = a / p快速求得另外一個約數q。
  • 好玩的數學第11講:數學軟體Mathematica內置函數的使用規則
    本講主要內容:基本數學函數及使用規則基本初等函數運算舉例及方法擴展規定:用於數學計算的函數簡稱為函數;把用於完成某項操作的命令函數簡稱為命令。Sqrt[x]:求平方根Exp[x]:自然常數為底的指數函數,它也有直觀的輸入形式,這裡的e是內部常數e符號。
  • Axure函數使用手冊
    返回-PI到PI之間的值,是從x軸正向逆時針旋轉到點(x,y)經過的角度。Math.ceil(x) :向上取整函數,獲取大於或者等於指定數值的最小整數。參數:x為數值。Math.cos(x) :獲取一個數值的餘弦函數。。返回-1.0到1.0之間的數。參數:x為弧度數值。Math.exp(x) :獲取一個數值的指數函數,計算以e為底的指數。參數:x為數值。
  • Python語言中使用pyqtgraph庫實現數據可視化
    背景在Python程式語言中,matplotlib是一種常用的用於數據可視化的繪圖庫,它提供了一套和matlab相似的命令API,開發者可以僅需幾行代碼,便可生成如直方圖,功率譜,條形圖,錯誤圖,散點圖等圖形,適用於交互式繪圖,而且也可以方便地將它作為繪圖控制項嵌入到GUI應用程式中
  • python計算平方和平方根的方法
    相反的開平方就是√ ̄(這裡我們只考慮正數),也就是求平方根。例如:16的平方根有4,64的平方根有8。python如何計算平方和平方根在python中,有多種方法可以求一個數的平方和平方根,可以使用:內置模塊、表達式、內置函數等實現。
  • MATLAB函數庫大全(收藏版)
    all測試向量中所用元素是否為真is*(一類函數)檢測向量狀態.其中*表示一個確定的函數(isinf)any測試向量中是否有真元素*isa檢測對象是否為某一個類的對象>exist檢驗變量或文件是否定義logical將數字量轉化為邏輯量find查找非零元素的下標3 語言結構與調試表3.1程式語言函數名功能描述函數名功能描述
  • 零基礎java入門教程函數function實例化格式案例void返回值說明
    將這個部分定義成一個獨立的功能,方便與日後使用java中對功能的定義是通過行數的形式來體現的,需要定義功能,完成一個整數*3+5的運算並列印結果由圖1演變出函數模塊功能修飾符public static .public可以不寫,static一定要用調用被靜態修飾的內容.整數類型int獨立的功能,獨立的封裝空間。
  • 淺談Java中的幾種隨機數
    最明顯的,也是直觀的方式,在Java中生成隨機數隻要簡單的調用:java.lang.Math.random() 在所有其他語言中,生成隨機數就像是使用Math工具類,如abs, pow, floor, sqrt和其他數學函數。大多數人通過書籍、教程和課程來了解這個類。一個簡單的例子:從0.0到1.0之間可以生成一個雙精度浮點數。
  • C語言編程求解:1到1000之間所有的素數
    我麼知道C語言有求餘數的運算符%,如果餘數是0,那麼說明能整除了。我們來寫程序代碼。這裡,說明一下,當你寫一個具有某個功能的代碼的時候,把這個功能寫成一個函數,而不是所有的代碼都放在main函數裡。在main函數裡調用這個你寫的函數。
  • Java8 lambda表達式
    編寫第一個lambda表達式swing是一個平臺無關的gui庫,在該庫中,有很多常見的習慣,比如為了知道用戶點點擊了什麼,註冊一個事件監聽器,這個事件監聽器可以執行一些操作響應用戶的輸入。如何在正確的場合使用lambda表達式?下面有幾個使用lambda表達式的例子①展示了在沒有參數的情況下如何使用lambda,可以使用一對空的小括號來表示沒有參數,這是一個實現了Runnable的lambda的表達式,該接口只有一個方法run(),該方法不接受任何參數,且返回void.
  • Python使用ctypes模塊調用DLL函數之C語言數組與numpy數組傳遞
    在Python語言中,可以使用ctypes模塊調用其它如C++語言編寫的動態連結庫DLL文件中的函數,在提高軟體運行效率的同時,也可以充分利用目前市面上各種第三方的DLL庫函數,以擴充Python軟體的功能及應用領域,減少重複編寫代碼、重複造輪子的工作量,這也充分體現了Python語言作為一種膠水語言所特有的優勢