2012-07-05 37 views
8
myInt = int(5 * myRandom()) 

myRandom() là một phao được tạo ngẫu nhiên, mà nên được 0.2.Truyền tới lỗi int và dấu chấm động?

Vì vậy, tuyên bố này nên đánh giá là 1.

Câu hỏi của tôi: có thể là do lỗi dấu phẩy động, nó KHÔNG được đánh giá là 1?

Ví dụ: nếu do lỗi dấu phẩy động, thứ gì đó phải là 0.2 có thể là LESS hơn số đó? IE, ví dụ xem xét 3 khả năng sau:

int(5 * 0.2)    = 1 //case 1 normal 
int(5 * 0.2000000000000001) = 1 //case 2 slightly larger, its OK 
int(5 * 0.1999999999999999) = 0 //case 3 negative, is NOT OK, as int() floors it 

case3 thậm chí có thể ?, với 0,1999999999999999 thể là kết quả của một lỗi điểm nổi? Tôi chưa bao giờ thực sự nhìn thấy một epsilon tiêu cực cho đến nay, chỉ có trường hợp 2, khi nó hơi lớn hơn một chút, và thats OK, như khi nó được đúc để int(), mà 'sàn' nó vào kết quả chính xác. Tuy nhiên với một epsilon âm, hiệu ứng 'sàn' sẽ làm cho kết quả là 0,9999999999999996 được đánh giá là 0.

+0

Tôi không nghĩ là có thể, không. Phép nhân và làm tròn chỉ nên chú ý đến số chữ số có thể có tối đa. – Ryan

+1

Nếu nó được tạo ngẫu nhiên, tại sao "nên" là 0,2? –

+0

Đây là C++, không C. Bạn không thể sử dụng cú pháp hàm dựng trong C. –

Trả lời

3

Không thể cho phép myRandom trả về .2 vì .2 không thể đại diện cho float hoặc double, giả sử hệ thống đích của bạn đang sử dụng tiêu chuẩn điểm động nhị phân IEEE 754, mặc định là mặc định.

Nếu myRandom() trả về số đại diện gần nhất .2, thì myInt sẽ là 1, vì số gần nhất .2 đại diện là phao lớn hơn .2 (0,20000000298023223876953125), và đại diện gần nhất gấp đôi (0.20000000000000001110223024625156540423631668090820312).

Trong các trường hợp khác, điều này sẽ không đúng. Ví dụ: số gần nhất là 0,69999999999999997779553950749686919152736663818359375, vì vậy myInt sẽ là 2, không phải là 3.

+0

Tôi thích câu trả lời của bạn là tốt nhất, tuy nhiên nó đáng lo ngại. Vấn đề thực sự là nếu tôi có thể nhận được một kết quả xác định bằng cách đúc một phao vào một int, tuy nhiên từ những gì bạn đã nói về 0,6, nó xuất hiện không. Tôi sẽ cần phải làm một số làm tròn tùy chỉnh. –

1

Có, có thể, ít nhất là theo tiêu chuẩn C có liên quan.

Giá trị 0.2 không thể được trình bày chính xác trong định dạng dấu phẩy động nhị phân. Do đó, giá trị được trả lại bởi myRandom() sẽ thấp hơn một chút hoặc cao hơn một chút so với giá trị toán học 0.2. Tiêu chuẩn C cho phép hoặc là kết quả.

Bây giờ có thể là ngữ nghĩa IEEE chỉ cho phép kết quả lớn hơn một chút so với 0.2 - nhưng tiêu chuẩn C không yêu cầu ngữ nghĩa IEEE. Và đó là giả định rằng kết quả được bắt nguồn chính xác nhất có thể từ giá trị 0.2. Nếu giá trị được tạo ra từ một loạt các hoạt động dấu phẩy động, mỗi giá trị có thể giới thiệu một lỗi nhỏ, nó có thể dễ dàng hoặc nhỏ hơn hoặc lớn hơn 0.2.

+0

Là phụ lục, hãy đúc phao vào vòng tròn int, vì vậy nếu giá trị lớn hơn 0,2, bạn sẽ kết thúc với một sản phẩm lớn hơn 1, sẽ làm tròn xuống. – Wug

+0

Đây chỉ là một ví dụ, myRandom() có thể là bất kỳ thứ gì từ 0 đến 1, nhưng 0,2 có vẻ như một trường hợp tốt để minh họa sự khác biệt giữa kết quả của 0 và 1. Vấn đề thực sự là về Xác định, tôi đang tìm cách tìm ra nếu đúc một Floatpoint đến một int, điều đó sẽ dẫn đến kết quả xác định. Có vẻ như không. –

1

Nó không phải là điểm động lỗi, đó là cách hoạt động của điểm nổi. Bất kỳ phân số nào không phải là 1/(lũy thừa của 2) không thể được biểu diễn chính xác và sẽ được làm tròn lên hoặc hoặc xuống tới số có thể biểu diễn gần nhất.

Bạn có thể sửa mã của mình bằng cách nhân với một số epsilon nhỏ hơn một trước khi chuyển thành số nguyên.

myInt = int(5 * myRandom() * 1.000000000000001) 

Xem What Every Computer Scientist Should Know About Floating-Point Arithmetic.

0

Có thể, tùy thuộc vào số bạn chọn. Để kiểm tra một số cụ thể, bạn luôn có thể in chúng với nhiều độ chính xác: printf ("% 1.50f", 0.2)

0

tại sao không nhân phao của bạn với 5.0 và sau đó sử dụng hàm tròn để làm tròn nó?

+0

Đây là một minh họa, những arent các số liệu thực tế. –

+0

Ý tưởng vẫn hoạt động. –

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