2011-10-29 24 views
6

Tôi đang sử dụng hàm pow trong C và lưu trữ giá trị trả về theo kiểu số nguyên. xem đoạn mã dưới đây:giá trị trả lại của pow() được làm tròn xuống nếu được gán cho một số nguyên

for (i = 0; i < 5; i++){ 
    val = (int)pow(5, i); 
    printf("%d, ", val); 
} 

đây ival là các số nguyên và đầu ra là 1, 5, 24, 124, 624. Tôi tin rằng điều này là do phao 25 ​​được coi là 24.99999 ... được làm tròn xuống 24 khi gán cho một số nguyên.

Làm cách nào tôi có thể vượt qua điều này nếu tôi vẫn cần lưu trữ giá trị trả về trong một int?

+0

'float' 25 không được coi là" '24.9 ...', 25 có thể được biểu diễn chính xác dưới dạng phao. Nó chỉ là 'pow' không hoàn toàn chính xác, và vì lý do nào đó trong dịp này đã bỏ lỡ thấp. Đối với nhiều giá trị, nó không thể hoàn toàn chính xác, vì câu trả lời đúng về mặt toán học không phải là một phao chính xác, nhưng đối với những tính toán này, nó có thể là vấn đề có chất lượng thực hiện hay không. –

+1

Xem thêm http://stackoverflow.com/questions/101439/the-most-efficient-way-to-implement-an-integer-based-power-function-powint-int để thảo luận về cách triển khai phiên bản nguyên của pow() –

+0

Không sử dụng 'pow' cho lũy thừa số nguyên. Có nhiều cách tốt hơn, an toàn hơn. Nhân tiện, bạn sẽ nhận được hành vi này trên nền tảng nào? Tôi nghĩ rằng một 'pow' tốt sẽ luôn chính xác cho các số nguyên trong đó kết quả chính xác phù hợp với' double'. –

Trả lời

9

Thêm 0.5 trước khi truyền tới int. Nếu hệ thống của bạn hỗ trợ nó, bạn có thể gọi hàm C99 round(), nhưng tôi muốn tránh nó vì lý do di chuyển.

+3

Có một sự khác biệt nhỏ, rằng 'vòng tròn 'đi từ số không, trong khi thêm 0,5 và đúc thành' int' làm tròn lên. Vì vậy, ví dụ 'vòng (pow (-0,5,1))' là -1, trong khi '(int) (pow (-0,5,1) + 0,5)' là 0. Vì vậy, người hỏi có thể cần phải quyết định cái nào họ muốn, mặc dù tất nhiên nếu câu trả lời là gần với một số nguyên nó không có sự khác biệt. –

+0

"vòng tròn đi từ số không, trong khi thêm 0,5 và đúc để int viên đạn lên" - cho giá trị một nửa số nguyên, ý tôi là. –

+0

@ JoelSpolsky: Cảm ơn bạn đã chỉnh sửa, nhưng 'round()' không được hỗ trợ trên tất cả các hệ thống. Tôi đã đủ điều kiện chỉnh sửa của bạn cho phù hợp. –

3

Tự mình thực hiện.

int myPow(int base, int exponent) { 
    int n = 1; 
    for (int i = 0; i < exponent; i++) { 
     n *= base; 
    } 
    return n; 
} 

Điều này, tất nhiên, chỉ xử lý số mũ dương và chỉ hoạt động trên int, và chắc chắn có nhiều cách hiệu quả hơn để thực hiện. Xem, ví dụ: the source for ^ in Haskell.

5

thay

val = (int)pow(5, i); 

với

double d = pow(5,i); 
val = (int)((d > 0.0) ? floor(d + 0.5) : ceil(d - 0.5)); 
-3

Tôi có vấn đề này bản thân tôi. Tôi giải quyết nó một cách dễ dàng trong hướng dẫn của bạn chỉ đơn giản là chỉ cần thêm nếu tuyên bố.

if (k%n>0) 
{ 
    k=k+1; 
} 
Các vấn đề liên quan