2017-05-29 23 views
-2

嗨,我正在做一些程序來尋找不同的正弦函數的解決方案。 我想SIN(2×),罪(4次),SIN(6×),...,SIN(12倍),並把它們存儲到陣列,這樣我可以測試每個函數的給定間隔的解決方案。如何把正弦函數中的多項式? (重新)

這裏的代碼...

#include <stdio.h> 
#include <math.h> 
#include <stdlib.h> 
#include <float.h> 

int bisect(double *x, double x0, double xf, double tolerance, double (*func)(double)); 


int main() 
{ 
    double x, x0 = 2.0, xf = 4.0, tolerance = FLT_EPSILON; 
    int status, i, j; 
    double (*pf[6])(double); 

    for (i = 1; i < 7; i++) 
    { 
     pf[i] = sin(2 * i * x); 
     // error : cannot assign double value to double(*) (double) entity 
     // How to make functions like sin(2x), sin(4x), .. etc?? 
     status = bisect(&x, x0, xf, tolerance, pf[i]); 

,我開了對開()函數查找在給定什麼時候函數返回0

平分功能是其主要功能如下。 x0是起點,xf是終點,我設置檢查錯誤的容差。平分函數在for循環中使用中間值定理。

我想通過調用函數開張for循環中,並提供使用* PF [I]正弦函數找到解決方案。

 if (status == -1) 
      printf("Error : bisect() failed, invalid tolerance\n"); 
     else if(status == -2) 
      printf("Error : bisect() failed, invalid end points\n"); 
     else 
      printf("x = %f, sin(x) = %g\n", x, pf[i](x)); 


    } 
    return 0; 
} 

int bisect(double *x, double x0, double xf, double tolerance, double (*func)(double)) 
{ 
    double xleft = x0, fleft; 
    double xright = xf; 
    double xmid, fmid; 

    if (tolerance <= 0.0) 
     return -1; 

    fleft = func(x0); 

    if (fleft * func(xf) > 0.0) 
     return -2; 

    xmid = (xleft+xright) /2.0; 
    fmid = func(xmid); 

    while (fabs(fmid) > tolerance) 
    { 
     if (fleft * fmid <= 0) 
     { 
      xright = xmid; 
     } 

     else 
     { 
      xleft = xmid; 
      fleft = fmid; 
     } 
     xmid = (xleft + xright)/2.0; 
     fmid = func(xmid); 

    } 
    *x = xmid; 
    return 0; 
} 

很容易找到罪(2個),罪(4次)等爲正弦,餘弦等解決方案,但什麼?我如何將這些函數存儲在* pf []? (函數指針陣列)

任何建議將是有益的。

+1

你已經在幾個小時前發佈了這個問題。這裏重新發布的帖子並不好。您應該編輯原稿並要求重新打開(如果已關閉)。請注意,這個不是更好。你在評論中得到了信息,你似乎沒有想過。閱讀[問]。我們不是一個輔導/編碼網站。 – Olaf

+0

@Olaf我的道歉。下次我會做得更好。感謝您的建議。 –

回答

3

在C它不可能做到你想要什麼,而不是無需創建多個功能包裝原始sin功能。

也許類似

double sin2(double value) 
{ 
    return sin(2 * value); 
} 

double sin4(double value) 
{ 
    return sin(4 * value); 
} 

// Etc... 

int main(void) 
{ 
    double (*pf[6])(double) = { 
     sin2, sin4, ... 
    }; 

    for (int i = 0; i < 6; ++i) 
    { 
     printf("%f\n", pf[i](0.5)); 
    } 
} 
+0

感謝您的幫助!你怎麼這麼容易? :) –

0

可悲的是,C不支持全面關閉,這是你似乎什麼希望。

但是,您應該能夠在程序中定義任何自定義函數以獲得double並返回double,並將其傳遞給您的對分函數。

例如:

double some_function(double x) { 
    // You can do anything you like, as long as you return a double. 
    return sin(2 * x); 
} 

在你的情況下,它可能是一個有點乏味有單獨指定的i每一個值的自定義功能,但你可能獲得通過使用去掉一些重複宏,如:

#define DEFINE_SIN_POLY(i) double sin_poly_##i##(double x) { \ 
    return sin(2 * i * x); \ 
} 

DEFINE_SIN_POLY(2); 
DEFINE_SIN_POLY(3); // etc. 

// then, you can simply access these functions as 
sin_poly_2, sin_poly_3, etc. 

但是,這有點難看。如果你使用C++,你可以採取更先進的功能,如函數類型,lambda表達式等優勢,使你的代碼更簡潔,在性能方面幾乎沒有損失。

+1

真的很有幫助。感謝您讓我的代碼避免長時間囉嗦。 –

+0

不客氣!很高興我可以幫助,即使有點。同樣,如前所述,如果您關心的只是快速構建算法和玩遊戲,那麼像C++甚至Python這樣的東西可能會讓您的工作效率更高。 –

0

您需要動態地創建函數,這些函數對某些參數具有某種記憶。您可以將這些參數設爲全局,或者創建所謂的closure

即使C本身不支持這樣的事情,您可以通過在具有所需行爲的堆上創建一個新函數來模擬它。有些圖書館可以幫助你做到這一點。

libffi就是這樣的一個庫,它允許你在C中創建一個閉包,儘管它是一種非常先進的技術。

的文檔提供了一些例子:http://www.chiark.greenend.org.uk/doc/libffi-dev/html/Closure-Example.html

0

的原因的錯誤是

pf[i] = sin(2 * i * x); 

調用sin()函數自變量等於2*i*x當前值。結果是該特定值的正弦,而不是函數。

本質上,標準C不支持閉包。

獲得所需要的效果,而不是試圖直接或間接地創造一個集合的循環中功能最簡單的方法,將是的bisect()規格從

int bisect(double *x, double x0, double xf, double tolerance, double (*func)(double)) 

發生變化,添加一個額外的參數

int bisect(double *x, double x0, double xf, double tolerance, double (*func)(double), double factor) 

,並在每一個地方func(something)被調用,改變func(something*factor)地方。例如,將fmid = func(xmid)更改爲fmid = func(xmid * factor)

然後,在呼叫方(main())從

for (i = 1; i < 7; i++) 
{ 
    pf[i] = sin(2 * i * x); 
    // error : cannot assign double value to double(*) (double) entity 
    // How to make functions like sin(2x), sin(4x), .. etc?? 
    status = bisect(&x, x0, xf, tolerance, pf[i]); 

改變循環到

for (i = 1; i < 7; i++) 
{ 
    // How to make functions like sin(2x), sin(4x), .. etc 
    status = bisect(&x, x0, xf, tolerance, sin, 2*i); 

注意,這消除了對陣列pf完全的需要。它的工作原理是將2*i的值傳遞給函數,如factor,然後可以使用它。

但是,更普遍的是,您需要花時間閱讀C教科書。試圖通過類比Python來學習C會導致各種各樣的問題,因爲Python支持C不支持的很多功能(如本例中的閉包),並且C中不能輕易模仿它們。它們是非常不同的語言,通常需要非常不同的方式來構建一個程序。

+0

這是非常乾淨的做事方式。謝謝你的幫助。我會繼續閱讀C書,而不是YouTube。 –