2008-12-09 31 views
36

Tôi là người mới sử dụng Erlang. Làm thế nào để bạn làm modulo (nhận phần còn lại của một bộ phận)? Đó là% trong hầu hết các ngôn ngữ giống như C, nhưng điều đó chỉ định một nhận xét trong Erlang.Làm thế nào để bạn làm modulo hoặc phần còn lại trong Erlang?

Một số người trả lời bằng rem, mà trong hầu hết mọi trường hợp đều ổn. Nhưng tôi đang xem xét lại điều này bởi vì bây giờ tôi cần phải sử dụng số âm và rem cung cấp cho bạn phần còn lại của một bộ phận, mà không giống như modulo cho số âm.

+3

Hoạt động modulo không có định nghĩa rõ ràng, btw cho C và C++% cho tiêu cực là phụ thuộc triển khai (ISO C90) sau này xác định chính xác như Erlang để biết chi tiết xem http://en.wikipedia.org/wiki/Modulo_operation –

Trả lời

33

Trong Erlang, 5 rem 3. cho 2 và -5 rem 3. cho -2. Nếu tôi hiểu câu hỏi của bạn, bạn sẽ muốn -5 rem 3. để tặng 1 thay vì, -5 = -2 * 3 + 1.

Điều này có làm những gì bạn muốn không?

mod(X,Y) when X > 0 -> X rem Y; 
mod(X,Y) when X < 0 -> Y + X rem Y; 
mod(0,Y) -> 0. 
+0

Điều này sẽ hoạt động. Nhưng có thực sự không có gì phân phối với erlang mà thực hiện điều này? – Matt

+0

Không theo hướng dẫn tham khảo erlang: http://erlang.org/doc/reference_manual/expressions.html (phần 6.12) – grifaton

+6

Cách khác: mod (X, Y) -> (X rem Y + Y) rem Y. – Koistinen

26

Nhà điều hành erlang modulo là rem

Eshell V5.6.4 (abort with ^G) 
1> 97 rem 10. 
7 
1

Erlang còn lại không làm việc với số âm, vì vậy bạn phải viết chức năng riêng của bạn cho các thông số tiêu cực.

2

Y + X rem Y ở trên có vẻ sai: hoặc (Y + X) rem Y hoặc Y + (X rem Y) cho kết quả không chính xác. Ví dụ: cho Y = 3. Nếu X = -4, biểu mẫu đầu tiên trả về -1, nếu X = -3, biểu mẫu thứ hai trả về 3, không có biểu mẫu nào trong [0; 3 [.

Tôi sử dụng này để thay thế:

% Returns the positive remainder of the division of X by Y, in [0;Y[. 
% In Erlang, -5 rem 3 is -2, whereas this function will return 1, 
% since -5 =-2 * 3 + 1. 

modulo(X,Y) when X > 0 -> 
    X rem Y; 

modulo(X,Y) when X < 0 -> 
    K = (-X div Y)+1, 
    PositiveX = X + K*Y, 
    PositiveX rem Y; 

modulo(0,_Y) -> 
    0. 
1
mod(A, B) when A > 0 -> A rem B; 
mod(A, B) when A < 0 -> mod(A+B, B); 
mod(0, _) -> 0. 

% console: 
3> my:mod(-13, 5). 
2 
1

Câu trả lời được chấp nhận là sai.

rem hoạt động chính xác như toán tử % trong hiện đại C. Nó sử dụng phân chia cắt ngắn.

Câu trả lời được chấp nhận thất bại cho X < 0 và Y < 0. Cân nhắc mod(-5,-3):

C:      -5 % -3 == -2 
rem:     -5 rem -3 == -2 
Y + X rem Y: -3 + -5 rem -3 == -5 !! wrong !! 

Các triển khai thay thế cho việc sử dụng toán tử modulo rối trí phân chia và phép chia có dư. Các kết quả cho những người đang

flooring division: -5 mod -3 == -2 
euclidean division: -5 mod -3 == 1 

Vì vậy

Y + X rem Y 

không sao chép bất cứ điều hành modulo cho X < 0 và Y < 0.

rem công trình như mong đợi - nó sử dụng cắt ngắn chia.

5

tôi đã sử dụng sau trong elixir:

defp mod(x,y) when x > 0, do: rem(x, y); 
defp mod(x,y) when x < 0, do: rem(x, y) + y; 
defp mod(0,_y), do: 0 

Xin đừng downvote này bởi vì nó là một ngôn ngữ khác hơn so với câu hỏi. Tất cả chúng ta đều sống trong giấc mơ, bởi vì tất cả chúng ta đều có chùm tia.

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