2010-08-30 15 views
135

Ví dụ,Hành vi của phân chia số nguyên là gì?

int result; 

result = 125/100; 

hoặc

result = 43/100; 

Sẽ cho kết quả luôn luôn là sàn của bộ phận? Hành vi được xác định là gì?

+0

Tóm tắt: *** đã ký * phân chia số nguyên cắt ngắn về không **. Đối với các kết quả không âm, điều này giống như sàn (tròn theo hướng -Infinity). (Hãy coi chừng C89 không đảm bảo điều này, xem câu trả lời.) –

Trả lời

135

Kết quả sẽ luôn là tầng của bộ phận? Bahavior được định nghĩa là gì?

Có, số nguyên thương của hai toán hạng.

6.5.5 khai thác chất nhân

Khi số nguyên được chia, kết quả của sự/nhà điều hành là thương đại số với bất kỳ phần phân đoạn loại bỏ. 88) Nếu a/b thương là biểu thị, biểu thức (a/b) * b + a% b phải bằng a.

và chú thích tương ứng:

88) Điều này thường được gọi là ‘‘cắt ngắn về phía zero’’.

Tất nhiên hai điểm cần lưu ý là:

Quá trình chuyển đổi số học thông thường được thực hiện trên các toán hạng.

và:

Kết quả của/nhà điều hành là thương từ các bộ phận của toán hạng đầu tiên của thứ hai; kết quả của toán tử% là số còn lại là . Trong cả hai hoạt động, nếu giá trị của toán hạng thứ hai là 0, hành vi không xác định.

[Ghi chú: tôi nhấn mạnh]

+11

... trừ khi, tất nhiên, bạn đang chia số âm bằng dương (hoặc v.v.), trong trường hợp đó nó sẽ là trần. –

+53

Nó không phải là sàn cũng không trần, nó là cắt ngắn của phần phân đoạn, nó là khái niệm khác nhau! – Wizard79

+25

@Will A: No. Nó được định nghĩa là cắt ngắn về 0. Gọi nó là bất cứ điều gì khác sẽ chỉ thêm vào sự nhầm lẫn vì vậy xin vui lòng không làm như vậy. –

11

Có, kết quả luôn bị cắt ngắn về 0. Nó sẽ quay về phía giá trị tuyệt đối nhỏ nhất.

-5/2 = -2 
5/2 = 2 

Đối với giá trị đã ký và không âm, giá trị này giống như sàn (làm tròn về hướng -Infinity).

+38

Cắt ngắn, * không * sàn. – dan04

+7

@ dan04: yep sàn sẽ chỉ hợp lệ cho số nguyên dương :) – Leonid

15

đâu kết quả là âm tính, C truncates về phía 0 chứ không phải là sàn - Tôi học được điều này đọc về việc tại sao phân chia số nguyên Python luôn tầng ở đây: Why Python's Integer Division Floors

+2

Tôi đồng ý với bình luận tự hỏi liệu có (neg% pos) đi tiêu cực là bao giờ hữu ích? Trên một lưu ý liên quan, tôi tự hỏi nếu hành vi yêu cầu arithmetically-không chính xác trong một số trường hợp "unsignedvar> signedvar" là bao giờ hữu ích? Tôi có thể hiểu lý do không đòi hỏi hành vi luôn chính xác; Tôi thấy không có lý do gì để yêu cầu hành vi sai. – supercat

+6

+1 cho một tài liệu tham khảo tuyệt vời về lý do tại sao sàn là hành vi chính xác để phân chia số nguyên (trái với định nghĩa của C, bị hỏng và hầu như không bao giờ hữu ích). –

+0

chính xác và chính xác. +1. –

33

Dirkgently cung cấp cho an excellent description của phân chia số nguyên trong C99, nhưng bạn cũng nên biết rằng trong phân chia số nguyên C89 với toán hạng phủ định có hướng thực hiện được xác định.

Từ dự thảo ANSI C (3.3.5):

Nếu một trong hai toán hạng là tiêu cực, cho dù kết quả của sự/nhà điều hành là số nguyên lớn nhất nhỏ hơn các thương đại số hoặc các số nguyên nhỏ nhất lớn hơn thương số đại số được xác định thực hiện, như là dấu hiệu của kết quả của toán tử%. Nếu a/b thương là đại diện, biểu thức (a/b) * b + a% b phải bằng a.

Vì vậy, hãy chú ý với số âm khi bạn gặp khó khăn với trình biên dịch C89.

Đó là một thực tế thú vị rằng C99 đã chọn cắt ngắn về 0 vì đó là cách FORTRAN đã làm điều đó. Xem this message trên comp.std.c.

+0

Và C99 dự thảo N1256 từ đầu đoạn 5 đề cập đến 'phân chia số nguyên đáng tin cậy' như một tính năng ngôn ngữ mới. Tuyệt vời '* - *'. –

+0

Cắt ngắn là cách phần cứng CPU phổ biến nhất (ví dụ: x86) hoạt động, vì vậy sẽ rất điên rồ khi thực hiện một lựa chọn khác. IDK xuất hiện trước tiên, ngữ nghĩa hay hành vi phần cứng của Fortran, nhưng không phải ngẫu nhiên mà cũng giống như vậy. –

10

Kết quả sẽ luôn là tầng của bộ phận?

Không. Kết quả thay đổi, nhưng biến thể chỉ xảy ra cho giá trị âm.

Hành vi được xác định là gì?

Để làm cho nó vòng sàn rõ ràng về phía vô cực tiêu cực, trong khi phân chia số nguyên viên đạn về phía zero (sẽ cắt cụt)

Đối với các giá trị tích cực mà họ đều giống nhau

int integerDivisionResultPositive= 125/100;//= 1 
double flooringResultPositive= floor(125.0/100.0);//=1.0 

Đối với giá trị tiêu cực này là khác nhau

int integerDivisionResultNegative= -125/100;//=-1 
double flooringResultNegative= floor(-125.0/100.0);//=-2.0