在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

帶大家領(lǐng)略sqrt的神奇之處:開(kāi)平方的7種算法介紹

算法與數(shù)據(jù)結(jié)構(gòu) ? 來(lái)源:未知 ? 2019-11-28 09:29 ? 次閱讀

作者:nash_

sqrt()函數(shù),是絕大部分語(yǔ)言支持的常用函數(shù),它實(shí)現(xiàn)的是開(kāi)方運(yùn)算;開(kāi)方運(yùn)算最早是在我國(guó)魏晉時(shí)數(shù)學(xué)家劉徽所著的《九章算術(shù)》被提及。今天寫了幾個(gè)函數(shù)加上國(guó)外大神的幾個(gè)神級(jí)程序帶大家領(lǐng)略sqrt的神奇之處。

1、古人算法(暴力法)

原理:從0開(kāi)始0.00001,000002...一個(gè)一個(gè)試,直到找到x的平方根,代碼如下:

publicclassAPIsqrt{

staticdoublebaoliSqrt(doublex){

finaldouble_JINGDU=1e-6;
doublei;
for(i=0;Math.abs(x-i*i)>_JINGDU;i+=_JINGDU)
;
returni;
}

publicstaticvoidmain(String[]args){
doublex=3;
doubleroot=baoliSqrt(x);
System.out.println(root);
}

測(cè)試結(jié)果:

1、7320509999476947

2、牛頓迭代法

計(jì)算機(jī)科班出身的童鞋可能首先會(huì)想到的是《數(shù)值分析》中的牛頓迭代法求平方根。原理是:隨意選一個(gè)數(shù)比如說(shuō)8,要求根號(hào)3,我們可以這么算:

(8 + 3/8) = 4.1875

(4.1875 + 3/4.1875) = 2.4519

(2.4519 + 3/2.4519) = 1.837

(1.837 + 3/1.837) = 1.735

做了4步基本算出了近似值了,這種迭代的方式就是傳說(shuō)中的牛頓迭代法了,代碼如下:

publicclassAPIsqrt{

staticdoublenewtonSqrt(doublex){

if(x0){
System.out.println("負(fù)數(shù)沒(méi)事開(kāi)什么方");
return-1;
}
if(x==0)
return0;

double_avg=x;
doublelast_avg=Double.MAX_VALUE;
finaldouble_JINGDU=1e-6;

while(Math.abs(_avg-last_avg)>_JINGDU){
last_avg=_avg;
_avg=(_avg+x/_avg)/2;
}
return_avg;
}

publicstaticvoidmain(String[]args){
doublex=3;
doubleroot=newtonSqrt(x);
System.out.println(root);
}
}

測(cè)試結(jié)果:

17320508075688772

3、暴力-牛頓綜合法

原理:還是以根號(hào)3為例,先用暴力法講根號(hào)3逼近到1.7,然后再利用上述的牛頓迭代法。雖然沒(méi)有用牛頓迭代好,但是也為我們提供一種思路。代碼如下:

publicclassAPIsqrt{

staticdoublebaoliAndNewTonSqrt(doublex){

if(x0){
System.out.println("負(fù)數(shù)沒(méi)事開(kāi)什么方");
return-1;
}
if(x==0)
return0;

doublei=0;
double_avg;
doublelast_avg=Double.MAX_VALUE;
for(i=0;i*i0.1);
_avg=i;

finaldouble_JINGDU=1e-6;

while(Math.abs(_avg-last_avg)>_JINGDU){
last_avg=_avg;
_avg=(_avg+x/_avg)/2;
}
return_avg;
}

publicstaticvoidmain(String[]args){
doublex=3;
doubleroot=baoliAndNewTonSqrt(x);
System.out.println(root);
}
}

測(cè)試結(jié)果:

1、7320508075689423

4、二分開(kāi)方法

原理:還是以3舉例:

(0+3)/2 = 1.5, 1.5^2 = 2.25, 2.25 < 3;

(1.5+3)/2 = 2.25, 2.25^2 = 5.0625, 5.0625 > 3;

(1.5+2.25)/2 = 1.875, 1.875^2 = 3.515625; 3.515625>3;

直到前后兩次平均值只差小于自定義精度為止,代碼如下:

publicclassAPIsqrt{

staticdoubleerfenSqrt(doublex){

if(x0){
System.out.println("負(fù)數(shù)沒(méi)事開(kāi)什么方");
return-1;
}
if(x==0)
return0;

finaldouble_JINGDU=1e-6;
double_low=0;
double_high=x;
double_mid=Double.MAX_VALUE;
doublelast_mid=Double.MIN_VALUE;

while(Math.abs(_mid-last_mid)>_JINGDU){

last_mid=_mid;
_mid=(_low+_high)/2;
if(_mid*_mid>x)
_high=_mid;
if(_mid*_midreturn_mid;

}

publicstaticvoidmain(String[]args){
doublex=3;
doubleroot=erfenSqrt(x);
System.out.println(root);
}
}

測(cè)試結(jié)果:

1、732051134109497

5、計(jì)算 (int)(sqrt(x))算法

PS:此算法非博主所寫

原理:空間換時(shí)間,細(xì)節(jié)請(qǐng)大家自行探究,代碼如下:

publicclassAPIsqrt2{
finalstaticint[]table={0,16,22,27,32,35,39,42,45,48,50,53,
55,57,59,61,64,65,67,69,71,73,75,76,78,80,81,83,84,
86,87,89,90,91,93,94,96,97,98,99,101,102,103,104,
106,107,108,109,110,112,113,114,115,116,117,118,119,
120,121,122,123,124,125,126,128,128,129,130,131,132,
133,134,135,136,137,138,139,140,141,142,143,144,144,
145,146,147,148,149,150,150,151,152,153,154,155,155,
156,157,158,159,160,160,161,162,163,163,164,165,166,
167,167,168,169,170,170,171,172,173,173,174,175,176,
176,177,178,178,179,180,181,181,182,183,183,184,185,
185,186,187,187,188,189,189,190,191,192,192,193,193,
194,195,195,196,197,197,198,199,199,200,201,201,202,
203,203,204,204,205,206,206,207,208,208,209,209,210,
211,211,212,212,213,214,214,215,215,216,217,217,218,
218,219,219,220,221,221,222,222,223,224,224,225,225,
226,226,227,227,228,229,229,230,230,231,231,232,232,
233,234,234,235,235,236,236,237,237,238,238,239,240,
240,241,241,242,242,243,243,244,244,245,245,246,246,
247,247,248,248,249,249,250,250,251,251,252,252,253,
253,254,254,255};

/**
*Afasterreplacementfor(int)(java.lang.Math.sqrt(x)).Completely
*accurateforx2147483648(i.e.2^31)...
*/
staticintsqrt(intx){
intxn;

if(x>=0x10000){
if(x>=0x1000000){
if(x>=0x10000000){
if(x>=0x40000000){
xn=table[x>>24]<8;
}else{
xn=table[x>>22]<7;
}
}else{
if(x>=0x4000000){
xn=table[x>>20]<6;
}else{
xn=table[x>>18]<5;
}
}

xn=(xn+1+(x/xn))>>1;
xn=(xn+1+(x/xn))>>1;
return((xn*xn)>x)?--xn:xn;
}else{
if(x>=0x100000){
if(x>=0x400000){
xn=table[x>>16]<4;
}else{
xn=table[x>>14]<3;
}
}else{
if(x>=0x40000){
xn=table[x>>12]<2;
}else{
xn=table[x>>10]<1;
}
}

xn=(xn+1+(x/xn))>>1;

return((xn*xn)>x)?--xn:xn;
}
}else{
if(x>=0x100){
if(x>=0x1000){
if(x>=0x4000){
xn=(table[x>>8])+1;
}else{
xn=(table[x>>6]>>1)+1;
}
}else{
if(x>=0x400){
xn=(table[x>>4]>>2)+1;
}else{
xn=(table[x>>2]>>3)+1;
}
}

return((xn*xn)>x)?--xn:xn;
}else{
if(x>=0){
returntable[x]>>4;
}
}
}

return-1;
}
publicstaticvoidmain(String[]args){
System.out.println(sqrt(65));

}
}

測(cè)試結(jié)果:8

6、最快的sqrt算法

PS:此算法非博主所寫

這個(gè)算法很有名,大家可能也見(jiàn)過(guò),作者是開(kāi)發(fā)游戲的,圖形算法中經(jīng)常用到sqrt,作者才寫了一個(gè)神級(jí)算法,和他那神秘的0x5f3759df,代碼如下

#include
floatInvSqrt(floatx)
{
floatxhalf=0.5f*x;
inti=*(int*)&x;//getbitsforfloatingVALUE
i=0x5f375a86-(i>>1);//givesinitialguessy0
x=*(float*)&i;//convertbitsBACKtofloat
x=x*(1.5f-xhalf*x*x);//Newtonstep,repeatingincreasesaccuracy
returnx;
}

intmain()
{
printf("%lf",1/InvSqrt(3));

return0;
}

測(cè)試結(jié)果:

感興趣的朋友可以參考http://wenku.baidu.com/view/a0174fa20029bd64783e2cc0.html 是作者解釋這個(gè)算法的14頁(yè)論文《Fast Inverse Square Root》

7、一個(gè)與算法6相似的算法

PS:此算法非博主所寫

代碼如下:

#include
floatSquareRootFloat(floatnumber){
longi;
floatx,y;
constfloatf=1.5F;

x=number*0.5F;
y=number;
i=*(long*)&y;
i=0x5f3759df-(i>>1);
y=*(float*)&i;
y=y*(f-(x*y*y));
y=y*(f-(x*y*y));
returnnumber*y;
}

intmain()
{
printf("%f",SquareRootFloat(3));

return0;
}

測(cè)試結(jié)果:


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 算法
    +關(guān)注

    關(guān)注

    23

    文章

    4615

    瀏覽量

    92991
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4333

    瀏覽量

    62697

原文標(biāo)題:開(kāi)平方的 7 種算法

文章出處:【微信號(hào):TheAlgorithm,微信公眾號(hào):算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    單片機(jī)開(kāi)平方的快速算法

    本帖最后由 scan0123 于 2012-8-13 14:52 編輯 單片機(jī)開(kāi)平方的快速算法為工作的需要,要在單片機(jī)上實(shí)現(xiàn)開(kāi)根號(hào)的操作。目前開(kāi)平方的方法大部分是用牛頓迭代法。我在查了一些資料
    發(fā)表于 08-02 14:40

    VeriLog 開(kāi)平方怎么做?

    VeriLog 開(kāi)平方怎么做?
    發(fā)表于 10-11 14:09

    關(guān)于開(kāi)平方算法

    電機(jī)算法中會(huì)用到開(kāi)平方算法,是個(gè)相對(duì)復(fù)雜和耗時(shí)些的數(shù)學(xué)算法C math庫(kù)的double sqrt耗時(shí)太長(zhǎng),不能用我沒(méi)有用過(guò)IQmath庫(kù),自
    發(fā)表于 09-27 11:27

    程序中定義了一個(gè)變量進(jìn)行sqrt()開(kāi)根號(hào)處理與預(yù)想的結(jié)果不對(duì)

    我在程序中定義了一個(gè)變量對(duì)其進(jìn)行sqrt()開(kāi)根號(hào)處理,結(jié)果與預(yù)想的不對(duì)。在TMS320F28335里面,執(zhí)行開(kāi)平方有什么注意的嗎?
    發(fā)表于 11-05 11:45

    圖像算法有什么神奇之處

    吳軍在《數(shù)學(xué)之美》中,用通俗易懂的語(yǔ)言,讓非專業(yè)讀者領(lǐng)略了一把數(shù)學(xué)的魅力。數(shù)學(xué)作為自然科學(xué)的基礎(chǔ),它的應(yīng)用遍及物理、工程、生物、化學(xué)和經(jīng)濟(jì)等多個(gè)領(lǐng)域,在拍照這樣一個(gè)似乎不太相關(guān)的領(lǐng)域,數(shù)學(xué)算法再一次
    發(fā)表于 09-17 09:05

    STC12C5A60S2無(wú)法實(shí)現(xiàn)開(kāi)平方算法怎么回事

    求助!STC12C5A60S2無(wú)法實(shí)現(xiàn)開(kāi)平方算法sqrt函數(shù)),以及atan2和asin怎么辦?我已經(jīng)包含了相關(guān)的頭文件了,但是編譯通不過(guò)。
    發(fā)表于 05-20 09:07

    在單片機(jī)中開(kāi)平方會(huì)用到哪些算法

    C語(yǔ)言中開(kāi)平方算法中要開(kāi)平方的話,可以在頭文件中加#include .然后調(diào)sqrt(n);函數(shù)即可.但在單片機(jī)中要開(kāi)平方.可以用到下面
    發(fā)表于 07-15 07:03

    基于定點(diǎn)DSP的浮點(diǎn)開(kāi)平方算法的實(shí)現(xiàn)

    本文提出了基于TMS320C2XX 定點(diǎn)DSP 的浮點(diǎn)開(kāi)平方算法,給出了實(shí)現(xiàn)方法及程序清單。實(shí)踐證明該方法具有精度高、運(yùn)算速度快、程序簡(jiǎn)單等特點(diǎn)。以美國(guó) TI 公司的TMS320C2XX 為代
    發(fā)表于 07-31 08:11 ?42次下載

    基于逐次逼近的VHDL開(kāi)平方算法

    Cyclone 器件為在FPGA 上實(shí)現(xiàn)低成本的數(shù)字信號(hào)處理(DSP)系統(tǒng)提供了一個(gè)理想的平臺(tái),成為大規(guī)模生產(chǎn)時(shí)的最佳方案.。本文介紹了在以EP1C6 芯片為核心的硬件系統(tǒng)中,運(yùn)用VHDL 實(shí)現(xiàn)
    發(fā)表于 11-30 14:14 ?32次下載

    MCS-51單片機(jī)實(shí)用子程序庫(kù)實(shí)驗(yàn)(六)

    標(biāo)號(hào): FSQR 功能:浮點(diǎn)數(shù)開(kāi)平方(快速逼近算法)入口條件:操作數(shù)在[R0]中。出口信息:OV=0時(shí),平方根仍在[R0]中,OV=1時(shí),負(fù)數(shù)開(kāi)平方
    發(fā)表于 01-08 10:11 ?54次下載

    電源變壓器設(shè)計(jì)與計(jì)算鐵心面積公式

    電源變壓器設(shè)計(jì)與計(jì)算鐵心面積公式:鐵心面積=容量開(kāi)平方;以100W為例;100開(kāi)平方=10平方厘米.電子管輸出變壓器的鐵心面積=容量開(kāi)平方*2.以15W輸出變壓器為例:15
    發(fā)表于 10-23 14:39 ?7919次閱讀
    電源變壓器設(shè)計(jì)與計(jì)算鐵心面積公式

    電力系統(tǒng)微機(jī)保護(hù)中開(kāi)平方運(yùn)算的一新的快速算法

    電力系統(tǒng)微機(jī)保護(hù)中開(kāi)平方運(yùn)算的一新的快速算法
    發(fā)表于 11-02 11:03 ?8次下載

    單片機(jī)快速開(kāi)平方算法資料和代碼免費(fèi)下載

    C語(yǔ)言中開(kāi)平方算法中要開(kāi)平方的話,可以在頭文件中加#include 。然后調(diào)sqrt(n);函數(shù)即可。但在單片機(jī)中要開(kāi)平方??梢杂玫较旅?/div>
    發(fā)表于 09-24 17:18 ?1次下載
    單片機(jī)快速<b class='flag-5'>開(kāi)平方</b>的<b class='flag-5'>算法</b>資料和代碼免費(fèi)下載

    單片機(jī)快速開(kāi)平方算法

    C語(yǔ)言中開(kāi)平方算法中要開(kāi)平方的話,可以在頭文件中加#include .然后調(diào)sqrt(n);函數(shù)即可.但在單片機(jī)中要開(kāi)平方
    發(fā)表于 11-11 13:36 ?1次下載
    單片機(jī)快速<b class='flag-5'>開(kāi)平方</b>的<b class='flag-5'>算法</b>

    NI Multisim 10經(jīng)典教程分享--除法與開(kāi)平方運(yùn)算電路

    NI Multisim 10經(jīng)典教程分享--除法與開(kāi)平方運(yùn)算電路
    的頭像 發(fā)表于 02-08 09:18 ?2216次閱讀
    主站蜘蛛池模板: 国产精品视频久久久久| 亚洲福利视频一区二区三区| 日日操狠狠操| 视频在线观看高清免费大全| 日日舔夜夜操| 国产亚洲片| 澳门久久| 8844aa在线毛片| 日一区二区三区| bl 高h文| 新四虎影院| 手机免费看a| 欧美黄色一级视频| 九色 在线| 91在线电影| 天天草夜夜骑| 国产精品无码永久免费888| 国产免费啪啪| 中文字幕色综合久久| 四虎成人欧美精品在永久在线| 欧美性video精品| 国产黄色大片又色又爽| 午夜高清免费观看视频| 濑亚美莉iptd619在线观看| 在线观看的黄网| 狠狠色噜噜狠狠狠狠五月婷| 天堂中文在线www| 久久国产乱子伦精品免费强| 夜夜骑天天干| 国产www在线播放| 日本一区二区不卡视频| 羞羞爱爱| 久久精品男人影院| 午夜黄色毛片| 色爱区综合激情五月综合激情| 二区三区| 人与牲动交xxxxbbbb高清| 丁香六月 久久久| 久插| 免费的很黄很色的床小视频| 色男人社区|