題目:任意長度數串,不使用sqrt函式,手工計算平方根?
要求只准用加/減/乘/除四則運算,不准使用power/sqrt等函式。
演算法如下:
1、以小數點為中心往兩邊每2位分隔為一組;
2、然後以組為單位,從左往右掃瞄計算;
3、先對第一組數,找個n*n最大但不超過第一組數的數n,作為結果r的第1位;
4、然後用第一組數減去n*n的餘數,作為下次計算的數首部,將下一組兩位往下移構成乙個新的待計算數w;
5、將第3步已得結果r乘以20作為除數首部+尾數x,再乘於x,使得結果t最大但不超過待計算數,x作為結果r的第2位;
6、然後用w減去t作為餘數,作為下次計算的數首部,將下一組兩位往下移構成乙個新的待計算數w;
7、然後再將已有結果r乘以20作為除數首部+尾數x,再乘於x,使得結果t最大但不超過待計算數w,x作為結果r的下一位;
8、重複6~7,直至達到你期望的精度位數為止
c/c++語言實現演算法
(貼上到這裡無格式對齊了,請自行格式化):
//以計算到小數點後32位為例;
//written by 凌志輝.
void square_root(char *psznum)
#define iszero(a) ( fabs(a) < 0.000001f)
#define precisioncnt 32
#ifdef win32
#define _itoa_ _itoa_s
#define _strcpy_ strcpy_s
#define _sprintf_ sprintf_s
#else
#define _itoa_ itoa
#define _strcpy_ strcpy
#define _sprintf_ sprintf
#endif
int i = 0, nprecisioncnt = 0;
double fleft = 0.0f, ftail = 0.0f;
double fnum = 0.0f, tmp = 0.0f;
bool beveninteger = false; //整數部分偶數字
bool bcalcdecimal = false; //開始計算小數部分
char *pdot = strstr(psznum, ".");
bool binteger = (null == pdot); //整數嗎
char szresult[1024] = ; //存結果r
char szcalcnum[1024] = ; //被除數w
char szdivision[1024] = ; //除數
char szzero[4] = ;
char *p = psznum;
char *r = szresult;
char *d = szdivision;
char *c = szcalcnum;
if (null == psznum)
return;
beveninteger = binteger ? (0 == strlen(psznum) % 2) : (0 == (pdot - psznum) % 2);
//1、先計算首部
*c++=*p++;
if (beveninteger)
*c++=*p++;
fleft = 0.0f;
fnum = atof(szcalcnum);
//第一組數的計算, 首位範圍[0~99]
for ( i = 1; i <= 9; i++)
if (i * i > fnum)
i--;
fleft = (fnum - i * i);
_itoa_((int)fleft, szcalcnum, 10);
c = szcalcnum + strlen(szcalcnum);
break;
if ( iszero(i * i - fnum) )
fleft = 0.0f;
c = szcalcnum;
break;
_itoa_(i, szresult, 10);
_strcpy_(szdivision, szresult);
r = szresult + strlen(szresult);
d = szdivision + strlen(szdivision);
//2、計算第二組數以及以後,由於int型位數最大只佔10位,故全採用double型
while (true)
if (0 == *p && iszero(fleft))
{ //正好完全平方數
*r = '\0';
break;
if (0 == *p && !iszero(fleft) && !bcalcdecimal)
{ //不是平方數,然後計算更多的小數部分
if (binteger) /*整數計算,補小數點*/
*r++ = '.';
bcalcdecimal = true;
if (bcalcdecimal)
nprecisioncnt++;
p = szzero;
if (nprecisioncnt > precisioncnt)
*r = '\0';
break;
//非整數運算,若遇到小數點
if (!binteger && '.' == *p)
*r++ = '.';
p++;
*c++=*p++; *c++=*p++;
tmp = 20 * atof(szdivision);
fnum = atof(szcalcnum);
ftail = ceil(fnum / tmp);
while ( (tmp + ftail) * ftail > fnum) ftail--;
*r++ = (char)(ftail + 48);
*d++ = (char)(ftail + 48);
fleft =fnum - (tmp + ftail) * ftail;
memset(szcalcnum, 0, 1024);
if ( !iszero(fleft) )
_sprintf_(szcalcnum, "%.0f", fleft);
c = szcalcnum + strlen(szcalcnum);
printf ("%s\n", szresult);
#undef _itoa_
#undef _strcpy_
#undef _sprintf_
呼叫示例:
square_root("59");
square_root("72.25");
技術派 不用sqrt手工計算平方根
題目 任意長度數串,不使用sqrt函式,手工計算平方根?要求只准用加 減 乘 除四則運算,不准使用power sqrt等函式。演算法如下 1 以小數點為中心往兩邊每2位分隔為一組 2 然後以組為單位,從左往右掃瞄計算 3 先對第一組數,找個n n最大但不超過第一組數的數n,作為結果r的第1位 4 然...
c 手工雙緩衝技術
using system using system.collections.generic using system.componentmodel using system.data using system.drawing using system.text using system.window...
技術派 epoll和IOCP之比較
直入正題 epoll 用於linux系統 iocp 是用於 windows epoll 是當事件資源滿足時發出可處理通知訊息 iocp 則是當事件完成時發出完成通知訊息。從應用程式的角度來看,epoll 本質上來講是同步非阻塞的 iocp 本質上來講則是非同步操作 舉例說明吧 有乙個列印店,有一台印...