2008-11-26 70 views
29

Giả sử ab đều là loại intb không khác. Xem xét kết quả thực hiện a/b trong các trường hợp sau đây:Phân tách số nguyên làm tròn với các số âm trong C++

  1. ab đều không âm.
  2. ab đều là số âm.
  3. Chính xác một trong số đó là số âm.

Trong trường hợp 1, kết quả được làm tròn xuống số nguyên gần nhất. Nhưng tiêu chuẩn nói gì về trường hợp 2 và 3? Một bản nháp cũ tôi tìm thấy trôi nổi trên Internet cho thấy rằng nó phụ thuộc vào việc thực hiện (có, thậm chí cả trường hợp 2) nhưng ủy ban đang nghiêng về hướng làm cho nó luôn luôn 'tròn về phía không.' Có ai biết những gì (mới nhất) tiêu chuẩn nói? Vui lòng chỉ trả lời dựa trên tiêu chuẩn, không phải những gì có ý nghĩa, hoặc những gì trình biên dịch cụ thể làm.

+1

Cơ hội nghiên cứu đáng kinh ngạc với bản chất trang 1200 của tiêu chuẩn. Tôi sẽ cung cấp cho nó một grep nhanh chóng và bỏ :) –

Trả lời

22

Theo sửa đổi tháng năm năm 2008,

Bạn nói đúng:

Các nhị phân/nhà điều hành sản lượng các thương, và các nhà điều hành% nhị phân mang lại thời gian còn lại từ các bộ phận của biểu thức đầu tiên bởi thư hai. Nếu toán hạng thứ hai của/hoặc% bằng không thì hành vi là không xác định; nếu không (a/b) * b + a% b bằng a. Nếu cả hai toán hạng đều không âm thì phần còn lại là không âm; nếu không, dấu hiệu của phần còn lại được xác định thực hiện75).

Note 75 nói:

Theo để làm việc được tiến hành đối với việc rà soát các tiêu chuẩn ISO C, thuật toán thuận lợi nhất để phân chia số nguyên theo nguyên tắc quy định tại tiêu chuẩn ISO Fortran, ISO/IEC 1539: 1991, trong đó thương số luôn được làm tròn về 0.

Rất có thể C++ sẽ tụt hậu C về mặt này. Khi nó đứng, nó không xác định nhưng họ có một mắt hướng tới thay đổi nó.

Tôi làm việc trong cùng một bộ phận như Stroustrup và với một thành viên của ủy ban. Những điều cần AGES để có được hoàn thành, và chính trị vô tận của nó. Nếu nó có vẻ ngớ ngẩn, nó có thể là.

+7

Báo cáo được trích dẫn là cũ. Nó ngày trở lại tiêu chuẩn C++ 98 và đề cập đến bản sửa đổi C99. C99 chỉ định làm tròn về 0 và C++ 11 theo sau. – Jed

7

Chỉ cần nhận xét. Bản thảo làm việc hiện tại cho tiêu chuẩn C++ thực sự sửa chữa vấn đề "được xác định thực hiện" và yêu cầu cắt ngắn về 0. Here là trang web của ủy ban và here là bản nháp. Vấn đề là ở trang 112.

17

Là một bản cập nhật cho câu trả lời khác:

Dự thảo cuối cùng của C++ 11, n3242 mà là dành cho mục đích thực tế hầu hết giống với tiêu chuẩn thực tế C++ 11, nói điều này trong 5.6 điểm 4 (trang 118):

Đối với toán hạng tích phân, toán tử tạo ra thương số đại số với bất kỳ phần phân số nào bị loại bỏ; (Xem ghi chú 80)

Note 80 tiểu bang (lưu ý rằng thuyết minh này là không quy chuẩn):

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

Point 4 tiếp tục nói rõ:

nếu thương a/b được biểu diễn trong các loại kết quả, (a/b) * b + a% b bằng một .

có thể được hiển thị để yêu cầu ký hiệu a%b giống như ký hiệu a (khi không phải không).

-1

Đôi khi chúng ta cần phải lùi lại một bước, và tìm kiếm chỉ ở cơ sở toán học của nó:

Với int x, int y

nếu int i1 = x/y và int i2 = x% y

sau đó y * i1 + i2 phải x

vì vậy, đây không phải là quá nhiều về tiêu chuẩn, nhưng chỉ có một cách này có thể có thể được. Nếu bất kỳ tiêu chuẩn nào cho phép nó theo bất kỳ cách nào khác, thì tiêu chuẩn là sai, và điều đó có nghĩa là ngôn ngữ bị hỏng.

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