發信人: hmkang@ms2.hinet.net (Tomas Kang) 日期: 21 Jan 2000 04:21:57 GMT +0800 標題: Re: 請問一下計算機的程式怎麼寫?像log,pi,sq之類的東西? 信群: tw.bbs.comp.language 看板: 來源: <01bf63c3$e3a9ecc0$LocalHost@hinet.net>:24183, t232-090.dialup.dj.net.tw 組織: 痴漢手扎 次寫入到主題 <3YUSiZ$tr3@BirdNest.infoX.Net>... > > 一直用別人寫好的東西,突然想到一個問題 > 到底pi,開根號,log這些東西要怎麼寫? pi是個已知常數, 程式裡頭若要用pi, 同其他已知的常數一樣, 通常是不需計算而直接代入的. FPU浮點運算器中有直接載入 此常數的FLDPI指令, 即為一例. 至於, 這個pi值是如何求出到上百萬位數的精確度的方法, 則 可以到這裡看看: http://home.istar.ca/~lyster/pi.html 開根號的方法有很多種, 浮點數可以先將假數取出再進行整數 的開根號, 再還原成浮點數, 也可以直接就在浮點數上計算(如 有人提到的牛頓法等), 關於整數的開根號, 可以趕快到 news:comp.graphics.algorithms 上去找找看, 最近有幾篇標 題為 Fast integer square root 的文章, 非常精彩, 其中有 多種開根號法(含source提供)可以參考. 若找不到, 可以到 http://www.dejanews.com 打入上述keyword搜尋. 基本上, 開根號是一個很重要的計算, 除了精確, 還得要速度快, 這是因為, 計算兩點之間的距離就要開一次根號, 而很多的應用 如CG/CAD/CAM/CAE是經常要計算距離的, 所以會有很多人會去研 究或是找尋是否有更快的法則, 特別是在以前沒有FPU的X86年代. 至於, Log等超越函式的計算, 當然首先想到的是泰勒展開法. 不 過, 如sin/cos/tan等重要函式, 也有其他快速的方法, 但一時 之間記不得那麼多, 手頭也沒資料(也沒用了). 倒是, 從CI-C86 (早期的XT/86級的C-Compiler)所附的函數庫Source中, 找出來log 的計算例, 列出給你參考: #include "errno.h" double log(val) double val; { int n; double f,znum,zden,z,w,aw,bw,rz,frexp(); if(val<=0.0){ errno=EDOM; return -1.0e300; } f=frexp(val,&n); znum=f-0.5; if(f>0.707106781186547){ znum-=0.5; zden=f*0.5+0.5; } else { n-=1; zden=znum*0.5+0.5; } z=znum/zden; w=z*z; bw=((w-0.356679777390346e2)*w+0.312032220919245e3)*w-0.769499321084948e3; aw=( -0.789561128874912e0 *w+0.163839435630215e2)*w-0.641249434237455e2; rz=z+z*(w*aw/bw); val=355; val/=512; val*=n; val+=rz-n*2.1219444005469e-4; return val; } 有興趣, 可以自己找相關的書籍研究. 不過, 在現今計算機領域裡, 這是很冷門的, 可以找到的書不多, 因為可以再著墨的不多了. -- 市隱 記得XT/86年代, 沒有浮點計算器的支援, 對某些應用軟體 而言, 如何加速程式的浮點計算, 是一個重頭戲. Compiler 所提供的函式庫(包含基本的加減乘除)當然是正確的, 但都 不一定是最快的... 唉! 現在的Programmer真是 "幸福". .