2009-05-22 58 views
6

Tôi đang cố gắng viết một hàm trong C++ để giải quyết X bằng phương trình bậc hai. Đây là những gì tôi đã viết ban đầu, mà dường như để làm việc càng lâu càng không có con số phức tạp cho một câu trả lời:Giải phương trình bậc hai trong C++

float solution1 = (float)(-1.0 * b) + (sqrt((b * b) - (4 * a * c))); 
solution1 = solution1/(2*a); 

cout << "Solution 1: " << solution1 << endl; 

float solution2 = (float)(-b) - (sqrt((b*b) - (4 * a * c))); 
solution2 = solution2/(2*a); 
cout << "Solution 2: " << solution2; 

Nếu, ví dụ, tôi sử dụng phương trình: x^2 - x - 6, tôi lấy giải pháp 3, -2 một cách chính xác.

Câu hỏi của tôi là làm thế nào tôi sẽ giải thích cho số phức .... ví dụ, đưa ra phương trình:

x^2 + 2x + 5

Giải quyết bằng tay, tôi sẽ nhận được -1 + 2i, -1 - 2i.

Vâng, tôi đoán hai câu hỏi, tôi có thể viết ở trên tốt hơn và cũng làm cho nó chiếm số phức?

Cảm ơn bạn đã trợ giúp!

+3

Những người khác cung cấp câu trả lời tốt vì vậy không có lý do gì để tôi cố gắng vượt qua chúng;) Tuy nhiên, nếu bạn muốn một giải pháp tổng quát hơn cho phương trình ax^2 + bx + c = 0, hãy nhớ rằng a = = 0 phải là giá trị hợp lệ. Điều này sẽ dẫn đến một phân chia bằng không, vì vậy bạn phải chăm sóc riêng trường hợp này. Trong trường hợp này nó có nghĩa là bạn bị bỏ lại với một phương trình tuyến tính với một gốc. Chúc mừng! – ralphtheninja

+0

Bạn ngụ ý rằng bạn quan tâm đến các rễ phức tạp, nhưng những hệ số phức tạp trong phương trình ban đầu thì sao? –

+1

Hệ số phức tạp đòi hỏi một cách tiếp cận hoàn toàn khác. Vì vậy, đó sẽ là câu hỏi tiếp theo :) * scurrs off và chuẩn bị một câu trả lời trước khi tay * – ralphtheninja

Trả lời

8

Something như thế này sẽ làm việc:

struct complex { double r,i; } 
struct pair<T> { T p1, p2; } 

pair<complex> GetResults(double a, double b, double c) 
{ 
    pair<complex> result={0}; 

    if(a<0.000001) // ==0 
    { 
    if(b>0.000001) // !=0 
     result.p1.r=result.p2.r=-c/b; 
    else 
     if(c>0.00001) throw exception("no solutions"); 
    return result; 
    } 

    double delta=b*b-4*a*c; 
    if(delta>=0) 
    { 
    result.p1.r=(-b-sqrt(delta))/2/a; 
    result.p2.r=(-b+sqrt(delta))/2/a; 
    } 
    else 
    { 
    result.p1.r=result.p2.r=-b/2/a; 
    result.p1.i=sqrt(-delta)/2/a; 
    result.p2.i=-sqrt(-delta)/2/a; 
    } 

    return result; 
} 

Bằng cách đó bạn sẽ có được kết quả trong một cách tương tự cho cả hai kết quả thực sự và phức tạp (kết quả thực chỉ có các thiết lập phần ảo 0). Có vẻ đẹp hơn với tăng cường!

chỉnh sửa: cố định cho điều delta và thêm một kiểm tra cho các trường hợp thoái hóa như a = 0. Đêm không ngủ ftl!

+0

Nếu sqrt thành công, kết quả là> = 0. Và nếu đối số là tiêu cực, chương trình của bạn bị treo. Bạn nên kiểm tra ký hiệu trước và tính toán sqrt sau đó. Nếu dấu hiệu sẽ là số âm, bạn đặt result.first.i = + sqrt (4 * a * c-b * b)/2/a. (Tại sao xác định loại của riêng bạn nếu có một chuẩn hoàn toàn tốt :: cặp ?) – MSalters

+0

phải là delta = b * b-4 * a * c và chỉ sqrt khi delta> = 0. delta = 0 hoặc a = 0 là các trường hợp hợp lệ khi chúng tôi có một gốc. Nếu a = b = 0 và c = 1 thì sao? –

+0

Điều gì xảy ra nếu? Đó không phải là một hàm bậc hai, và phần/2/a sẽ thất bại. Điều này hoạt động khá tốt nếu delta = 0, ngoại trừ việc bạn sẽ trả lại kết quả tương tự hai lần. – MSalters

4

Bạn ít nhiều có, chỉ cần kiểm tra xem phần bên trong căn bậc hai có âm hay không và sau đó theo dõi riêng phần đó trong phần giảm của bạn.

3

Làm phụ trang: Khi chia, luôn kiểm tra xem mẫu số có bằng không. Và hãy nhớ cho các số dấu phảy để sử dụng một cái gì đó như:

#inlcude <float.h> 
if (fabs(a) < FLT_EPSILON) 
    then a is considered 0 
3

Bạn có thể về cơ bản chỉ cần sử dụng std::complex<float> thay vì float để có được sự hỗ trợ cho số phức.

1

nicking ý tưởng từ Blindy:

typedef std::complex<double> complex; 
using std::pair; 
pair<complex> GetResults(double a, double b, double c) 
{ 
    double delta=(b*b-4*a*c); 
    double inv_2a = 1/2/a; 
    if(delta >= 0) { 
    double root = sqrt(delta); 
    return std::make_pair(
     complex((-b-root)*inv_2a), 
     complex((-b+root)*inv_2a); 
    } else { 
    double root = sqrt(-delta); 
    return std::make_pair(
     complex(-b*inv_2a, -root*inv_2a)), 
     complex(-b*inv_2a, +root*inv_2a))); 
    } 
} 
20

Một lưu ý quan trọng đối với tất cả điều này. Các giải pháp được hiển thị trong các phản hồi này và trong câu hỏi ban đầu không mạnh mẽ.

Các giải pháp nổi tiếng (-b + - sqrt (b^2 - 4ac))/2a được biết đến là không mạnh mẽ trong tính toán khi ac là rất nhỏ compered để b^2, bởi vì một là trừ hai giá trị rất giống nhau. Tốt hơn là sử dụng giải pháp ít được biết hơn 2c/(-b - + sqrt (b^2 -4ac)) cho gốc khác.

Một giải pháp mạnh mẽ có thể được tính như sau:

temp = -0.5 * (b + sign(b) * sqrt(b*b - 4*a*c); 
x1 = temp/a; 
x2 = c/temp; 

Việc sử dụng các dấu hiệu (b) đảm bảo rằng chúng tôi không trừ hai giá trị tương tự.

Đối với OP, hãy sửa đổi điều này cho các số phức như được hiển thị bởi các áp phích khác.

+1

+1 điều này đáng kể tính toán mạnh mẽ hơn '(-b +/- sqrt (b * b - 4 * a * c))/(2a)'. BTW: vì 'temp' có thể là 0.0, nên thường cần kiểm tra trước khi phân chia. (e. g. a, b, c = 1,0,0). – chux

+0

'temp' chỉ có thể là 0 nếu' b' là 0 –

-1

Tôi đã thử chương trình mà không sử dụng tiêu đề 'math.h' và cũng đã thử logic khác ... nhưng chương trình của tôi chỉ có thể trả lời các phương trình bậc hai có hệ số 'x square' là một ..... hệ số của 'x' có thể được biểu thị bằng cách thêm hai số là các thừa số của hằng số không đổi. ví dụ: x vuông + 8x + 16; x vuông + 7x + 12; v.v. ở đây 8 = 4 + 4 & 16 = 4 * 4; ở đây hệ số của x có thể được biểu diễn như là một bổ sung của hai con số đó là các yếu tố của hằng số 16 ... Bản thân tôi không hoàn toàn hài lòng với nó nhưng đã thử một cái gì đó khác nhau, mà không sử dụng công thức để giải phương trình bậc hai. mã;

 #include<iostream.h> 
     #include<conio.h> 
     class quadratic 
       { 
       int b,c ; 
       float l,k; 
       public: 
       void solution(); 
       }; 
     void quadratic::solution() 
      { 
       cout<<"Enter coefficient of x and the constant term of the quadratic eqn where coefficient of x square is one"; 
       cin>>b>>c; 

       for(l=1;l<b;l++) 
        { 
        for(k=1;k<b;k++) 
        { 
        if(l+k==b&&l*k==c) 
         { 
          cout<<"x="<<-l<<"\t"<<"or"<<"\t"<<"x="<<-k; 
          cout<<"\n"; 
         } 
        } 
       } 
      } 
       void main() 
       { 
        quadratic a; 
        clrscr(); 
        a.solution(); 
        getch(); 
       } 
Các vấn đề liên quan