2009-06-10 43 views
31

Tôi tiếp tục gặp lỗi trong khi lập trình iPhone khi cố gắng sử dụng pi. Tôi đang cố gắngpi trong Mục tiêu C

float pNumber = 100*cos(2 * pi * (days/23)); 

Nhưng tôi nhận được lỗi mà nói:

_pi, tham chiếu từ

_pi $ non_lazy_ptr

tôi thấy ở đâu đó trên internet để sử dụng M_PI và nó biên dịch nhưng Tôi không nghĩ rằng nó mang lại cho tôi tính toán chính xác.

Khi tôi cố gắng:

float pNumber = 100*cos(2 * M_PI * (15746/23)); 

tôi nhận được 0

Cảm ơn

+0

Đầu tiên, tôi sẽ làm cho các hằng số của tôi nổi. – Nosredna

Trả lời

55
  • Việc phân chia số nguyên có lẽ cần phải bị cưỡng chế vào một điểm nổi một (đúc một trong những con số để một double - hoặc sử dụng ký hiệu 23.0 để chỉ ra rằng bạn muốn một phân chia dấu chấm động).
  • Thử in M_PI và xem nội dung hiển thị (printf("M_PI = %16.9g\n", M_PI); trong C).
  • Bạn có bao gồm tuyên bố cho cos() không? Nếu không, nó có thể được hiểu là một hàm trả về một số nguyên (có lẽ là #include <math.h>).

Ví dụ mã (thử nghiệm trong C trên Solaris 10 SPARC với GCC 4.3.3):

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

int main(void) 
{ 
    float pNumber = 100*cos(2 * M_PI * (15746/23)); 
    printf("M_PI = %16.9g\n", M_PI); 
    printf("pNum = %16.9g\n", pNumber); 
    pNumber = 100*cos(2 * M_PI * (15746/23.0)); 
    printf("pNum = %16.9g\n", pNumber); 
    return 0; 
} 

đầu ra Ví dụ:

M_PI =  3.14159265 
pNum =    100 
pNum =  -77.5711288 
+0

Làm thế nào để bạn đúc một int vào một float trong mục tiêu C? – Xcoder

+2

Mục tiêu-C là một siêu sao hoàn hảo (tôi nghĩ) của C, vì vậy bạn có thể làm theo cách tương tự như trong C. – Nosredna

+0

Tôi đã thử này ngày = (phao) ngày; float pNumber = 100 * cos (2 * pi * (ngày/23)); Vẫn không hoạt động. Tôi nhận được 0. Đây là những gì tôi đang tring để làm: http://stackoverflow.com/questions/975959/generate-a-periodic-value-based-on-dates – Xcoder

4

C/C++ và do đó Objective C/C++ không quảng bá số nguyên cho phao nổi khi thực hiện phân chia bình thường.

Vì vậy, trong C/C++, biểu thức 15746/23 đánh giá thành 567, chứ không phải 567.71207 như bạn có thể kỳ vọng.

C sẽ thúc đẩy số nguyên để nổi khi cần thiết nếu một hoặc toán hạng khác là một phao, vì vậy tất cả các bạn cần làm là sử dụng 15.746,0 hoặc 23,0 trong biểu hiện của bạn, tức là thay đổi để

float pNumber = 100*cos(2 * M_PI * (15746/23.0)); 

100 sẽ tự động được quảng cáo vì cos trả về một float (thực sự là một double, nhưng tôi sẽ bỏ qua các vấn đề percissions/double). Các 2 được thăng lên một phao vì M_PI là một phao. Và 15746 được thăng lên một phao vì 23.0 là một phao.

Tuy nhiên, nó sẽ không làm tổn thương thêm 0,0 cho tất cả các hằng số, ví dụ:

float pNumber = 100.0*cos(2.0 * M_PI * (15746.0/23.0)); 
+0

Cảm ơn lời đề nghị tuyệt vời Peter tuy nhiên, tôi vẫn đang làm điều gì đó sai trái. Tôi đang cố gắng để có được một số từ 0 đến 100. Đây là thỏa thuận, 15746 là số ngày kể từ ngày sinh nhật. Cứ sau 23 ngày tôi muốn đạt đến đỉnh điểm là 100. nếu bạn chia 12 thì bạn sẽ nhận được "thung lũng" bằng 0. Vì vậy, tôi muốn có thể nhận được số ngày của bất kỳ ngày nào và xem con số đó nằm giữa 1 và 0 dựa trên mỗi 23 ngày.Công thức này đã được đề nghị như là cách để tìm thấy nó bởi hai người, nhưng tôi nhận được số 15746. Bất cứ đề nghị? – Xcoder

+0

@Robb thế còn bạn cho chúng tôi thấy toàn bộ chương trình? Chúng tôi chỉ nhìn thấy một dòng ở đây và ở đó. Hãy cho chúng tôi chương trình nhỏ nhất làm những gì bạn nói. Và cho chúng tôi biết trình biên dịch C của bạn là gì và bạn đang chạy hệ điều hành nào. – Nosredna

+0

Robb, cos trả về kết quả với phạm vi từ -1,0 đến 1.0 và sau đó bạn nhân với 100,0, do đó kết quả phải có phạm vi từ -100,0 đến 100,0. Vì vậy, tôi không thể thấy làm thế nào bạn có thể nhận được 15746. Thật vậy, ở trên sẽ tạo ra -77.571128. Bạn sẽ phải đăng thêm mã, tốt hơn là một hàm mẫu hoàn chỉnh. –

1

Vấn đề là việc phân chia số nguyên ở phần sâu thẳm nhất của biểu thức, mà truncates giá trị (bỏ qua phần phân đoạn). Một tùy chọn, như đã đề cập, là làm cho mọi hằng số một số dấu chấm động, hoặc bằng cách thêm ".0" hoặc "f" sau nó. Ngoài ra, bạn có thể bỏ qua các dấu ngoặc đơn từ biểu thức bên trong nhất định.Vì M_PI là một số dấu chấm động, và phép nhân trong C là trái kết hợp (có nghĩa là nó tiến hành từ trái sang phải) phép nhân đầu tiên (2 * M_PI) sẽ được đẩy lên một phao, mỗi lần nhân lên kế tiếp. Vì cos() trả về một phao, pNumber sẽ được gán một phao mà không thực hiện bất kỳ phân chia số nguyên nào, do đó không mất chính xác. (Lưu ý: Thường thì không nên dựa vào sự kết hợp của nhà điều hành hoặc ưu tiên, nhưng trong trường hợp này tôi chỉ đang cố gắng chứng minh rằng nó thực sự hoạt động.)

Theo phạm vi số bạn nên thấy , nhớ lại rằng cosin (chưa sửa đổi) dao động từ -1 đến +1, không phải từ 0 đến 1, vì vậy bạn thực sự sẽ thấy -100 đến 100 (theo lý thuyết). Để có phạm vi chính xác, bạn muốn thêm 1, sau đó nhân với 50.

Ngẫu nhiên, lỗi biên dịch bạn nhận được trong trường hợp đầu tiên là do pi không được xác định. Hướng dẫn sử dụng M_PI là chính xác - đối với hằng số toán học, nó luôn thông minh hơn (và nhất quán hơn) để sử dụng những gì hệ thống cung cấp. Nếu bạn tò mò, trên Leopard, các hằng số này là #defined trong Math.h, dòng 528-540. Bạn có thể mở tệp bằng cách sử dụng Tệp> Mở nhanh ... (Cmd-Shift-D) và nhập "Math.h" hoặc nhấp đúp vào M_PI trong mã của bạn trong khi giữ phím Command.

+0

cần bao nhiêu độ chính xác? .. hằng số M_PI được định nghĩa là gì? .. 355/113 sẽ đánh giá điều gì? –

0

Tại sao lại sử dụng sinusoid?

Nếu mục tiêu là để có một fonction dao động từ 0 đến 100 sau đó 100-0 trong 23 ngày, bạn có thể sử dụng:

// x ranges from 0 to 2 
float x = (days % 23)/11.5; 
// pNumber is a saw ranging from 0 to 100 
float pNumber = 100 * abs(x - 1); 

Bạn cũng có thể thay thế x bởi một cosin nếu bạn thực sự muốn một , như 2 * pi/23 ~ = 0.273, bạn có

float x = 1 + cos((days % 23)*0.273);