2009-05-25 30 views
10

Hãy xem xét điều này:Tại sao toán tử mô-đun không hoạt động gấp đôi trong C#?

double x,y; 
x =120.0; 
y = 0.05; 

double z= x % y; 

Tôi cố gắng này và dự kiến ​​kết quả là 0, nhưng nó xuất hiện 0,04933333.

Tuy nhiên,

x =120.0; 
y = 0.5; 
double z= x % y; 

đã thực sự đã đưa ra kết quả chính xác của 0.

gì đang xảy ra ở đây?

Tôi đã thử Math.IEEERemainder(double, double) nhưng không trả về 0. Chuyện gì đang xảy ra ở đây?

Ngoài ra, như một sang một bên, cách thích hợp nhất để tìm phần còn lại trong C# là gì?

+0

Thật thú vị khi biết bạn đang cố gắng đạt được điều gì. Sử dụng mô-đun với số điểm dấu chấm động không bao giờ là một ý tưởng hay vì các câu trả lời đã có trạng thái. – VVS

Trả lời

14

Do định dạng lưu trữ, double không thể lưu trữ mọi giá trị chính xác như được nhập hoặc hiển thị. Biểu diễn con người của các số thường ở định dạng thập phân, trong khi double s được dựa trên hệ thống kép.

Trong một double, 120 được lưu trữ chính xác vì đó là giá trị số nguyên. Nhưng 0.05 thì không. Giá trị được tính gần bằng số gần nhất với số 0.05 nó có thể đại diện. 0.5 là một sức mạnh của 2 (1/2), do đó, nó có thể được lưu trữ chính xác và bạn không nhận được một lỗi làm tròn.

Để có tất cả các số chính xác giống như cách bạn nhập/hiển thị số trong hệ thập phân, hãy sử dụng decimal để thay thế.

decimal x, y; 
x = 120.0M; 
y = 0.05M; 

decimal z = x % y; // z is 0 
+0

Một 'double' luôn là giá trị chính xác. Hoạt động xác định giá trị của nó có thể không chính xác. 'double a = 0.1;' -> 'a' có giá trị chính xác có thể hơi khác với 0.1. 'double b = 0.125;' -> 'b' có giá trị chính xác bằng 0,125 toán học. Vẫn còn ý tưởng tốt để sử dụng 'thập phân'. – chux

+2

"giá trị chính xác có thể hơi khác" == không chính xác. –

+0

Với số nguyên, thương số của 7 chia cho 3 là 2 và khác với thương số toán học của 2.333 .... nhưng số nguyên được coi là chính xác. Tương tự như với FP, 7.0 chia cho 3.0 kết quả trong một câu trả lời gần, nhưng không giống như, giá trị của toán học 2.333 ... Trong cả hai trường hợp, các hoạt động không chính xác giống như toán học. Trong cả hai trường hợp, kết quả là chính xác. – chux

9

Bạn có thể làm một cái gì đó như:

double a, b, r; 

a = 120; 
b = .05; 

r = a - Math.floor(a/b) * b; 

Điều này sẽ giúp;)

0

Modulus nên chỉ được sử dụng với số nguyên. Phần còn lại đến từ một bộ phận euclide. Với gấp đôi, bạn có thể có kết quả không mong muốn.

Xem this article

+2

bạn có thể sử dụng mô-đun một cách an toàn với số thập phân. –

1

Tôi tin rằng nếu bạn đã cố gắng cùng với decimal nó sẽ hoạt động đúng.

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