台灣最大程式設計社群網站
線上人數
1037
 
會員總數:245150
討論主題:189053
歡迎您免費加入會員
討論區列表 >> C/C++ >> 請教各位前輩:數值分析的function , 以及 double 的準確度
[]  
[我要回覆]
1
回應主題 加入我的關注話題 檢舉此篇討論 將提問者加入個人黑名單
請教各位前輩:數值分析的function , 以及 double 的準確度
價值 : 30 QP  點閱數:3590 回應數:7

樓主

Berger
門外漢
0 1
58 5
發送站內信

請較一下各位前輩:
  我想做一個數值分析用的程式,但是遇到了一些問題...

我想讓使用者可以自行輸入一個方程式去讓電腦跑近似解...
但是不知道該怎麼把輸入的資料給轉成給電腦的方程式...
之前在寫多項式的時候我用的方法是再宣告一個 int fun[] 陣列去記錄每個冪次的值,
並用迴圈去跑sum+=fun[i]*pow(x,i);
但是卻不知道該怎麼寫才能用到sin,cos,exp等等...
因為像這些sin,cos,exp等等我裡面還想放自變數x的運算式進去,也不能先算值算好後放著(x值會一直變)...
所以想請教一下各位前輩,我該怎麼寫會比較好?
也請各位前輩指教一下,我之前多項式的寫法是不是有更好的方法可以解決?
因為有些多項式的冪次不一定是int,而是double...
謝謝各位前輩熱心的指導 ^^

另外,我之前有寫的一個簡單的二分法去求根,但是我用double去跑時,發現沒辦法跑的很精準,
像double用迴圈由-3.0加上0.0001跑到-0.47時,會自動減去0.0000001,變成-0.470001,-0.460001這樣...
而後來就沒辦法跑到0.0,而是0.9999999...
然後接下來的正數部分就會變成1.999999,2.999999這樣,我該怎麼做才能修正它?

搜尋相關Tags的文章: [ 數值分析 ] , [ function ] , [ double ] , [ 多項式 ] , [ ] ,
本篇文章發表於2005-05-01 22:11
別忘捐VP感謝幫助你的人 新手會員瞧一瞧
1樓
先把多項式po出來看看吧
sin...的用法很簡單啊, 就是要注意裡面祇接受"弳度"
不曉得您遇到的問題在哪裡?

至於不準確的部分, 那很正常..本來就是內定到小數下六位
可用 %20.12f 之類的..印出更精確的部分
不過他有極限, 忘記多少了

至於會有後面那個問題..我覺得..先po程式碼看看, 搞不好根本寫的有問題也不一定
本篇文章回覆於2005-05-03 15:30
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
2樓
作者回應

Berger
檢舉此回應
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<math.h>

void main()
{
char c;
char keyin[50];
char *pc;
int fun[20];
int value;
int sing;
int i;
int tum;

float a,b,d;
double j;
int e;
float s1,s2;

printf("請輸入所要堪根的方程式:\n( ex. -7x7+3x3-2x2+1x1 )\n");
scanf("%s%c",&keyin,&c);
pc=keyin;
value=0;
sing=1;
tum=0;
for(i=0;i<20;i++)
{fun[i]=0;}
for(i=0;i<strlen(keyin);i++)
{
if((*(pc+i))=='x')
{
tum=value*sing;
value=0;
}
else if((*(pc+i))=='+' || (*(pc+i))=='-')
{
fun[value]=tum;
switch((*(pc+i)))
{
case '+':sing=1;break;
case '-':sing=-1;break;
default:break;
}
value=0;
tum=0;
}
else if((*(pc+i))>='0' && (*(pc+i))<='9')
{
value=value*10+(*(pc+i))-'0';
}
else
{printf("\n輸入資料型態錯誤\n");break;}
}
fun[value]=tum;
/*
for(i=0;i<20;i++)
{printf("%d\t%d\n",i,fun[i]);}
*/

printf("請輸入所要勘根的下限:");
scanf("%d%c",&e,&c);a=(float)e;
printf("請輸入所要勘根的上限:");
scanf("%d%c",&e,&c);b=(float)e;
printf("請輸入所要勘根精確度:");
scanf("%f%c",&d,&c);
printf("在區間 %f 與 %f 內,精確度為 %f,找到的根有:\n",a,b,d);
s1=0;
for(e=0;e<20;e++)
{s1=s1+fun[e]*pow(a,e);}
//printf("%f\t%f\n",a,s1);
if(s1<=0.000001 && s1>=-0.000001)
{printf("找到一根為:%f \n",a);}
for(j=a+d;j<=b;j=j+d)
{
s2=0;
for(e=0;e<20;e++)
{s2=s2+fun[e]*pow(j,e);}
//printf("%f\t%f\n",j,s2);
if(s2<=0.000001 && s2>=-0.000001)
{printf("找到一根為:%f \n",j);}
else if(s1>0 && s2<0 && (s1>0.000001 || s1<-0.000001))
{printf("找到一趨近根為:%f \n",j-0.5*d);}
else if(s1<0 && s2>0 && (s1>0.000001 || s1<-0.000001))
{printf("找到一趨近根為:%f \n",j-0.5*d);}
s1=s2;
}
printf("堪根結束\n");
}
本篇文章回覆於2005-05-03 22:49
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
3樓
作者回應

Berger
檢舉此回應
所以我希望做到的是使用者能輸入像 10x3*sin(x2+10x)/exp(x3) ...等等方程式下去跑值...
我之後會把他用到微分積分中,就得要用迴圈一直讓x代不同的值下去跑...
所以我不太清楚怎麼讓使用者所輸入的方程式(字串)轉成我能帶值用的方程式...
簡單的講,就是有沒有方法能讓我使用他像一個function(double x)...把x值丟進去就可以給我整個方程式的值...
這個堪根做的很投機,我沒有用迴圈或是遞迴讓她去跑更近似的值,只是取個大概而已...
不過如果把值全部印出來就會發現我說的值會自己改變了...
本篇文章回覆於2005-05-03 23:03
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
4樓
作者回應

Berger
檢舉此回應
Please~ 幫幫忙吧~ T.T 各位大大~ <(_ _)>
本篇文章回覆於2005-05-08 21:46
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
5樓
10x3*sin(x2+10x)/exp(x3)
這裡面的東西是什麼啊
10x3----> 是指10x的3次方嗎

這等於另外還要作方程式parse的功能
呵呵
複雜度稍微高了那麼一點點
c語言時代作這個太辛苦了
.net的話..聊個天的時間就寫完了 ^__^
本篇文章回覆於2005-05-08 22:34
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
6樓
作者回應

Berger
檢舉此回應
是的~
最主要就是做方程式parse...

10x3----> 是指10x的3次方
這個方程式只是舉個例子

因為被限制用C++寫 ( 我用 Visual C++ 6.0 寫的),而且我也很想搞清楚這到底該怎麼做會比較好~
本篇文章回覆於2005-05-09 17:26
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
7樓
其實也不太難
就是用字串處理指令...一個字一個字讀取出來
自己實作囉, 必須動用到堆疊....這在.net裡面根本已經有現成的stack物件, c裡面就要自己做
ex:
有串指令
10x2+ 3x
把x, +-*/這些符號當作分隔...
所有的空白都假裝沒看到
由左而右掃, 會依序得到10, 2, 3
然後...對於每個x前後的數字...抓來和x作運算以後會得到一些值..(因為使用者會代入x值)
通通做好加減乘除的運算以後, 會得到最後的數值
若要求sin (10x2+3x) 那就再把這個數值代入...這樣就可以得到答案了

這個部分因為說明需要很多的篇幅, 建議還是去仔細的翻一下資料結構的書
裡面對於這種分析字串來作運算的動作幾乎都會有詳細介紹
本篇文章回覆於2005-05-09 22:13
== 簽名檔 ==
--未登入的會員無法查看對方簽名檔--
   
1

回覆
如要回應,請先登入.