Tính toán và trả về giá trị sin(x) xấp xỉ theo công thức

lập trình


Viết hàm với nguyên mẫu:
nhân đôi mySin(gấp đôi x, nhân đôi epsi);
tính toán và trả về giá trị sin(x) xấp xỉ theo công thức:
sin(x) = – + -… +(-1)n
ở đây n là số nguyên đầu tiên | |  epsi được thỏa mãn.

Những gì tôi đã thử:

   double q3() {
       int x;
       int n = 1;
       double p = 0;
       int dau = -1;
       int tongquat2 = 1.0 / (2 * n + 1);
       while (tongquat2 >= 1e-10) {
           tongquat2 = 1.0 / (2 * n + 1);
           p += -1 * dau * pow(-1, n) * pow(x, 2 * n + 1) / (giaithua(2 * n + 1));
           dau *= -1;
           n++;
       }
       return p;
   }
int main(){
   int x;
   scanf("%d", &x);
   printf("sin(%d)= %.6lf", x, q3());
}

tại sao mã không chính xác? giúp tôi những lỗi sai.

Giải pháp 1

Có ba loại lỗi có thể xảy ra ở đây và chúng tôi không biết đó là lỗi nào:
1) Lỗi biên dịch/liên kết: bạn cố gắng biên dịch ứng dụng của mình và nhận được sự cố được báo cáo trước khi ứng dụng có thể chạy. Nếu tôi cố gắng biên dịch mã của bạn như được hiển thị, tôi phải thêm hai dòng sau:

C
#include <stdio.h>
#include <math.h>

và cũng thêm một “định nghĩa giả” của giaithua để có được một bản biên dịch rõ ràng về mã bạn hiển thị.
Cho đến khi bạn có một bản biên dịch rõ ràng, bạn sẽ không tạo được tệp EXE và ứng dụng của bạn không thể chạy.
2) Lỗi thời gian chạy: những lỗi này khiến ứng dụng của bạn không thể tiếp tục vì đã xảy ra sự cố mà hệ thống không thể giải quyết được – chẳng hạn như lỗi “chia cho 0” hoặc cố gắng đọc một tệp không tồn tại. =Hệ thống hiển thị thông báo lỗi cho bạn và tắt ứng dụng của bạn ngay lập tức.
Chúng tôi không thể giúp bạn khắc phục điều đó nếu không biết thông báo đó là gì, nó xảy ra ở đâu và bạn đã nhập dữ liệu gì để nhận được thông báo đó.
3) Lỗi logic: điều này có nghĩa là bạn nhận được kết quả không mong muốn nhưng ứng dụng của bạn không gặp sự cố. Ví dụ: nếu bạn mong đợi ứng dụng của mình cho kết quả là 42 nhưng thay vào đó nó lại mang lại cho bạn 666.
Chúng tôi không thể giúp bạn khắc phục điều đó nếu không biết giá trị là gì, bạn mong đợi nhận được gì, khi nào bạn nhận được và dữ liệu nào bạn đã nhập để nhận được nó.

Tôi sẽ giả sử đây là một trong hai vấn đề cuối cùng và quá trình tìm ra vấn đề cần mã chạy với dữ liệu của bạn – cả hai điều chúng tôi đều không có. Biên dịch không có nghĩa là mã của bạn đúng! :cười:

Vì vậy, điều đó sẽ tùy thuộc vào bạn, nhưng bạn không phải tự mình thực hiện.
Hãy nghĩ về quá trình phát triển như viết một email: biên dịch thành công có nghĩa là bạn đã viết email bằng ngôn ngữ phù hợp – ví dụ như tiếng Anh, thay vì tiếng Đức – không phải email đó có chứa thông điệp bạn muốn gửi hay không.

Vì vậy, bây giờ bạn bước vào giai đoạn phát triển thứ hai (trên thực tế là giai đoạn thứ tư hoặc thứ năm, nhưng bạn sẽ đến các giai đoạn sớm hơn sau): Kiểm tra và gỡ lỗi.

Bắt đầu bằng cách xem nó làm gì và nó khác với những gì bạn muốn như thế nào. Điều này rất quan trọng vì nó cung cấp cho bạn thông tin về lý do tại sao nó lại làm như vậy. Ví dụ: nếu một chương trình nhằm mục đích cho phép người dùng nhập một số và nhân đôi số đó và in ra câu trả lời, thì nếu đầu vào/đầu ra sẽ như thế này:

Input   Expected output    Actual output
  1            2                 1
  2            4                 4
  3            6                 9
  4            8                16

Sau đó, khá rõ ràng rằng vấn đề nằm ở bit nhân đôi nó – nó không cộng chính nó với chính nó hoặc nhân nó với 2, nó nhân nó với chính nó và trả về bình phương của đầu vào.
Vì vậy, bạn có thể xem mã và rõ ràng là nó ở đâu đó ở đây:

C#
private int Double(int value)
   {
   return value * value;
   }

Khi bạn đã biết điều gì có thể xảy ra, hãy bắt đầu sử dụng trình gỡ lỗi để tìm hiểu lý do. Đặt điểm dừng trên dòng đầu tiên của phương thức và chạy ứng dụng của bạn. Khi đạt đến điểm ngắt, trình gỡ lỗi sẽ dừng và trao quyền kiểm soát cho bạn. Giờ đây, bạn có thể chạy mã theo từng dòng một (được gọi là “một bước”) và xem xét (hoặc thậm chí thay đổi) nội dung biến nếu cần (bạn thậm chí có thể thay đổi mã và thử lại nếu cần).
Hãy suy nghĩ xem mỗi dòng trong mã sẽ làm gì trước khi bạn thực thi nó và so sánh điều đó với những gì nó thực sự làm khi bạn sử dụng nút “Bước qua” để thực hiện lần lượt từng dòng. Nó có làm được điều bạn mong đợi không? Nếu vậy, hãy chuyển sang dòng tiếp theo.
Nếu không, tai sao không? Nó khác nhau như thế nào?
Hy vọng rằng điều đó sẽ giúp bạn xác định phần nào của mã đó có vấn đề và vấn đề là gì.
Đây là một kỹ năng và là một kỹ năng rất đáng để phát triển vì nó giúp ích cho bạn trong thế giới thực cũng như trong quá trình phát triển. Và giống như tất cả các kỹ năng, nó chỉ được cải thiện khi sử dụng!

Giải pháp 2

Không cần phải xem xét kỹ hơn hàm q3(), bạn có thể thấy rõ rằng nó không thể tính sin() vì không có tham số nào được truyền vào.

C
int main() {
    int x;
    scanf("%d", &x);
    printf("sin(%d)= %.6lf", x, q3());
}

//biên tập:
Thoạt nhìn, trình biên dịch cảnh báo bạn về điểm này:

C
int n = 1;
int tongquat2 = 1.0 / (2 * n + 1);
while (tongquat2 >= 1e-10) { ...

Chuyển đổi từ “double” sang “int”, có thể mất dữ liệu!
Các kiểu dữ liệu liên quan không phù hợp và lỗi tràn số học cũng có thể xảy ra.

Ngay cả khi giaithua() trả về một giá trị có ý nghĩa, điều đáng chú ý là x không được khởi tạo.

コメント

タイトルとURLをコピーしました