2013-04-25 25 views
14

Bất cứ ai có thể giải thích tại sao b được làm tròn ở đây khi tôi chia nó bằng một số nguyên mặc dù nó là một phao?Tại sao chia hai số nguyên không nhận được một phao?

#include <stdio.h> 

void main() { 
    int a; 
    float b, c, d; 
    a = 750; 
    b = a/350; 
    c = 750; 
    d = c/350; 
    printf("%.2f %.2f", b, d); 
    // output: 2.00 2.14 
} 

http://codepad.org/j1pckw0y

+5

"Tại sao?" - Bởi vì ngôn ngữ được thiết kế theo cách đó. Nếu bạn muốn một 'float', trước tiên bạn chuyển sang' float'. – Mysticial

+0

Chỉ vì phía bên tay trái của một nhiệm vụ là một phao không có nghĩa là phía bên tay phải đã được - nó chỉ có nghĩa là phía bên phải phải cung cấp _equal hoặc ít precision_ rằng một phao, do đó trình biên dịch không có lý do để làm cho nó bất cứ điều gì khác hơn là int. – ApproachingDarknessFish

+0

Vì 'a' và' 350' là 'int'. –

Trả lời

26

Điều này là do chuyển đổi tiềm ẩn. Biến số b, c, d thuộc loại float. Nhưng toán tử / thấy hai số nguyên nó phải chia và do đó trả về một số nguyên trong kết quả được chuyển đổi hoàn toàn thành một số float bằng cách thêm dấu thập phân. Nếu bạn muốn phân chia phao, hãy thử làm cho hai toán hạng thành các phao nổi /. Như sau.

#include <stdio.h> 

int main() { 
    int a; 
    float b, c, d; 
    a = 750; 
    b = a/350.0f; 
    c = 750; 
    d = c/350; 
    printf("%.2f %.2f", b, d); 
    // output: 2.14 2.14 
    return 0; 
} 
+4

Kết quả không được ** đúc ** thành phao. Một ** cast ** là một cái gì đó * rõ ràng * mà lập trình viên làm. Kết quả là ** được chuyển đổi hoàn toàn ** từ 'int' thành' float'. Thuật ngữ là quan trọng. –

+1

Cảm ơn. Tôi sẽ chỉnh sửa nó ở đây và chăm sóc nó trong tương lai. :) –

+0

Có. Không thể tin rằng tôi đã bỏ lỡ điều đó. Tôi chỉ cần sao chép mã của OP và sửa các dòng 'float'. Tôi sẽ sửa lỗi này ngay bây giờ. :) –

0

Có lẽ lý do tốt nhất là bởi vì 0xfffffffffffffff/15 sẽ cung cấp cho bạn một câu trả lời sai lầm khủng khiếp ...

+1

Tại sao lại là downvote? Kỳ vọng rằng phân chia số nguyên cho kết quả chính xác có lẽ là lý do tốt nhất để phân chia không nên ngầm "đẩy mạnh" thành loại dấu phẩy động. (Ngẫu nhiên, đây là một trong những điều khiến Lua đối xử với những con số ghê gớm khi làm việc.) –

+0

Câu hỏi * có thể * được hiểu là “Tại sao' int/int' không được đánh giá là float ** vì tôi gán nó ngay lập tức vào một biến nổi **? ”. Câu trả lời của bạn, mặc dù sâu sắc, không giải quyết những gì * có thể * thực sự là sự hiểu lầm của OP. Ngoài ra, có thể nó đã bị downvoted vì nó quá ngắn gọn. Tôi nghĩ về nó trong năm phút và tôi đã đi đến kết luận rằng nó rất buồn cười và/hoặc sâu sắc về một lý do khác với lý do bạn đã đưa ra. –

9

Sử dụng casting các loại:

int main() { 
    int a; 
    float b, c, d; 
    a = 750; 
    b = a/(float)350; 
    c = 750; 
    d = c/(float)350; 
    printf("%.2f %.2f", b, d); 
    // output: 2.14 2.14 
} 

Đây là một cách khác để giải quyết rằng:

int main() { 
     int a; 
     float b, c, d; 
     a = 750; 
     b = a/350.0; //if you use 'a/350' here, 
         //then it is a division of integers, 
         //so the result will be an integer 
     c = 750; 
     d = c/350; 
     printf("%.2f %.2f", b, d); 
     // output: 2.14 2.14 
    } 

Tuy nhiên, trong cả hai trường hợp, bạn nói với trình biên dịch rằng 350 là một phao và không phải là số nguyên. Do đó, kết quả của phép chia sẽ là một phao, và không phải là số nguyên.

+1

Điều này có tạo ra kết quả tương tự không? 'b = (phao) a/350;' – mushroom

+0

Vâng, đúng vậy. Bạn cần phải nhập bất kỳ một cái nào vào một 'float'. –

+6

Thực ra, '350.0' là một' double', và kết quả của phép toán sẽ là 'double' mà sau đó được chuyển thành' float' cho phép gán. '350.0f' sẽ là' float'. –

2

"a" là một số nguyên, khi được chia với số nguyên, nó cung cấp cho bạn số nguyên. Sau đó, nó được gán cho "b" như một số nguyên và trở thành một phao.

Bạn nên làm điều đó như thế này

b = a/350.0; 
0

Chia hai số nguyên sẽ dẫn đến một số nguyên (số nguyên) kết quả.

Bạn cần truyền một số dưới dạng phao hoặc thêm một số thập phân vào một trong các số, như/350.0.

1

Cụ thể, điều này không làm tròn kết quả của bạn, nó cắt ngắn về 0. Vì vậy, nếu bạn chia -3/2, bạn sẽ nhận được -1 và không -2. Chào mừng bạn đến với toán học không thể thiếu! Quay lại trước khi các CPU có thể thực hiện các hoạt động điểm nổi hoặc sự ra đời của các bộ xử lý toán học, chúng tôi đã làm mọi thứ với toán học tích phân. Mặc dù có các thư viện cho toán toán dấu chấm động, chúng quá đắt (trong hướng dẫn CPU) cho mục đích chung, vì vậy chúng tôi đã sử dụng giá trị 16 bit cho toàn bộ phần của một số và 16 giá trị khác cho phần.

EDIT: Câu trả lời của tôi làm cho tôi nghĩ về ông già cổ điển nói "khi tôi bằng tuổi các bạn ..."

2

Chapter and verse

6.5.5 khai thác chất nhân
...
6 Khi số nguyên được chia, kết quả của toán tử / là thương số đại số với bất kỳ phần nào được loại bỏ . 105) Nếu thương số a/b là biểu thị, biểu thức (a/b)*b + a%b phải bằng a; nếu không, hành vi của cả hai số a/ba%b là không được xác định.

105) Điều này thường được gọi là ‘cắt ngắn về không’ ’.

Chia một số nguyên cho một số nguyên cho kết quả số nguyên. 1/2 sản lượng 0; gán kết quả này cho một biến dấu chấm động cho 0,0. Để có được một kết quả dấu chấm động, ít nhất một trong các toán hạng phải là một loại dấu phẩy động. b = a/350.0f; sẽ cho bạn kết quả mong muốn.

Các vấn đề liên quan