2012-06-20 4 views
14

Tôi đã thấy nó ở một số nơi mà (int)someValue không chính xác và thay vào đó là sự cố được gọi cho hàm round(). Sự khác biệt giữa hai là gì?biến biến thành hàm int vs round()

Cụ thể, nếu cần thiết, đối với C99 C. Tôi cũng đã thấy cùng một vấn đề trong chương trình của tôi khi viết chúng trong java.

+0

Điều thú vị nữa mà tôi chưa từng nghe trước đây: "Vòng tới gần nhất là chế độ làm tròn IEEE mặc định." - https://randomascii.wordpress.com/2014/01/27/theres-only-four-billion-floatsso-test-them-all/ – cmp

Trả lời

14

Trong trường hợp đúc một giá trị float/double để int, bạn thường mất các phân đoạn phần do nguyên cắt ngắn.

Điều này khá khác biệt so với làm tròn như chúng ta thường mong chờ, vì vậy ví dụ 2.8 kết thúc lên như 2 với cắt ngắn số nguyên, cũng giống như 2.1 sẽ kết thúc như 2.

Cập nhật:

Một nguồn gốc tiềm năng (tổng) không chính xác với đúc là do phạm vi giới hạn của các giá trị có thể được biểu diễn bằng số nguyên thay vì với các loại dấu phẩy động (nhờ @R nhắc chúng ta về điều này trong phần bình luận bên dưới)

+0

Tôi không hiểu tại sao những bộ vấn đề này (compeition hoặc cho csvard trực tuyến của cs50) sử dụng round() và yêu cầu học sinh đặc biệt sử dụng int để chúng tròn _down_. Đó là khá khó chịu không bạn nghĩ sao? Dù sao, cảm ơn bạn. – cmp

+1

Một vấn đề khác khi truyền hoặc chuyển đổi hoàn toàn thành số nguyên là các giá trị độ lớn đã bị hủy. Ngay cả khi bạn muốn có kết quả toàn bộ số, tốt nhất là giữ một loại dấu phẩy động để số lượng lớn được giữ nguyên. Các hàm như 'round',' floor', 'rint', v.v. có thể thực hiện điều này. –

+0

@r * tuyệt vời * điểm, phạm vi giá trị có thể được biểu diễn chắc chắn bị giới hạn với số nguyên. Tôi nghĩ rằng tôi sẽ thêm một lưu ý về điều này để trả lời của tôi. Cảm ơn. – Levon

6
  1. Đúc thành int cắt bớt một số dấu phẩy động, tức là, nó sẽ giảm phần phân số.
  2. Hàm round trả về số nguyên gần nhất. Các trường hợp nửa chừng được làm tròn từ 0, ví dụ: round(-1.5)-2round(1.5)2.

7.12.9.6 Các chức năng vòng

Tóm tắt

#include <math.h> 
double round(double x); 
float roundf(float x); 
long double roundl(long double x); 

Mô tả

Các round chức năng vòng tranh luận của họ với neare st giá trị số nguyên trong định dạng dấu chấm động, làm tròn các trường hợp cách nửa chừng từ số không, bất kể hướng làm tròn hiện tại.

Returns

Các round chức năng trả về giá trị số nguyên làm tròn.

Nguồn: tiêu chuẩn C99 (ISO/IEC 9899:1999). Phần này không thay đổi trong tiêu chuẩn C11 (ISO/IEC 9899:2011).

(Đối với những người quan tâm, here là một giới thiệu rõ ràng đối với các thuật toán làm tròn.)

+1

Chỉ cần lưu ý, hành vi làm tròn có thể thay đổi theo mong đợi và theo ngôn ngữ. Ví dụ, gần đây tôi đã phát hiện ra rằng Python 3.x làm tròn về phía con số * thậm chí * gần nhất. Nó thực sự đã ném tôi đi. Vì vậy, nó luôn luôn là tốt để kiểm tra tài liệu. Tôi tin từ những ngày lập trình C của tôi rằng hành vi của C là phù hợp hơn với những kỳ vọng chung. – Levon

+0

@Levon Thú vị ... và đáng sợ :) – kol

+0

Yup, hoàn toàn làm tôi ngạc nhiên. Nó được gọi là "làm tròn của ngân hàng". – Levon

1

Cụ thể cho C, nó là (có lẽ) đúng trong hầu hết các trường hợp đó sẽ cắt cụt đúc, tuy nhiên, bạn nên luôn luôn kiểm tra kết quả để chắc chắn.

Vấn đề với quá trình truyền là, nó có thể HAY cắt ngắn HOẶC tròn. Những gì nó phụ thuộc phần lớn vào ngôn ngữ lập trình, nhẹ nhàng trên trình biên dịch cụ thể được sử dụng. Điều đó có nghĩa là không có quy tắc chung cho kết quả sẽ luôn áp dụng.

Vòng() được sử dụng phổ biến để tạo kết quả tương tự như làm tròn toán học. Có một trường hợp cạnh cần phải được theo dõi cụ thể cho .5, đôi khi làm tròn tới số chẵn tiếp theo.