Có gì khác biệt giữa các chế độ khác


133

Bạn tôi nói rằng có sự khác biệt giữa "mod" và "phần còn lại".

Nếu vậy, những khác biệt trong C và C ++ là gì? Liệu '%' có nghĩa là "mod" hay "rem" trong C?


2
Nó có thể không được định nghĩa cho các toán hạng âm.
Basile Starynkevitch

1
Tôi không phải là người C :( vì vậy không thể trả lời câu hỏi này trong ô trả lời. Nhưng vui lòng xem bài viết này :)
bonCodigo

1
% là phần còn lại. Trả lời chi tiết tại đây -> blog.msdn.com/b/ericlippert/archive/2011/12/05/ Khăn
wim

1
Câu hỏi có nghĩa là không có gì cho đến khi bạn xác định chính xác các điều khoản có nghĩa là gì.
David Heffernan

14
@David: câu hỏi là về ý nghĩa của các điều khoản. Nếu bạn nói rằng câu hỏi không có ý nghĩa gì, mặc dù nhiều người hiểu nó theo cách mà người hỏi dự định, thì tôi nghĩ bạn phải nói cụ thể hơn ý của bạn bằng từ "nghĩa là gì" ;-)
Steve Jessop

Câu trả lời:


140

Có một sự khác biệt giữa mô đun và phần còn lại. Ví dụ:

-21mod 43bởi vì -21 + 4 x 63.

Nhưng -21chia 4cho cho -5với một phần còn lại của -1.

Đối với các giá trị tích cực, không có sự khác biệt.


22
% có nghĩa là rem trong C.
banuj

22
@Jinxiao: trong C89, nó được xác định theo cách triển khai: %luôn luôn là phần còn lại, nhưng nó cũng có thể là mô đun (tức là luôn luôn dương), vì trong phân chia số nguyên C89 được phép làm tròn theo vô cực âm thay vì về 0. Vì vậy, trong C89, -5 / 2có thể -2với phần còn lại -1hoặc -3phần còn lại 1, việc thực hiện chỉ cần ghi lại. C99 loại bỏ tính linh hoạt, vì vậy bây giờ -5 / 2là luôn luôn -2.
Steve Jessop

2
Trên thực tế, không rõ mô-đun là gì. Dường như có nhiều định nghĩa khác nhau, tùy thuộc vào ngữ cảnh và ngôn ngữ. Xem bài viết trên wikipedia về modulo_operation. Trong một số bối cảnh, nó thực sự giống như phần còn lại.
Rudy Velthuis

9
Ai đó có thể giải thích các bước trong tính toán đầu tiên? Làm thế nào -21mod 43? Tại sao tính toán là -21 + 4 x 6?
Oz Edri

13
@OzEdri Để có được một số mod 4, bạn thêm bất kỳ số nguyên nào của 4 để có một số từ 0 đến 3. Đối với -21, số nguyên đó là 6 vì -21 + 4 x 6nằm trong khoảng từ 0 đến 3.
David Schwartz

47

Liệu '%' có nghĩa là "mod" hay "rem" trong C?

Trong C, %phần còn lại 1 .

..., Kết quả của /toán tử là thương số đại số với bất kỳ phần phân số nào bị loại bỏ ... (Điều này thường được gọi là "cắt ngắn về không".) C11dr §6.5.5 6

Các toán hạng của %toán tử phải có kiểu nguyên. C11dr §6.5.5 2

Kết quả của /toán tử là thương số từ việc chia toán hạng thứ nhất cho toán tử thứ hai; kết quả của %toán tử là phần còn lại ... C11dr §6.5.5 5


Có gì khác biệt giữa các chế độ khác

C không định nghĩa "mod", chẳng hạn như hàm mô đun nguyên được sử dụng trong phép chia Euclide hoặc modulo khác . "Mod Euclid" khác với a%bhoạt động của C khi aâm.

 // a % b
 7 %  3 -->  1  
 7 % -3 -->  1  
-7 %  3 --> -1  
-7 % -3 --> -1   

Modulo như phân chia Euclide

 7 modulo  3 -->  1  
 7 modulo -3 -->  1  
-7 modulo  3 -->  2  
-7 modulo -3 -->  2   

Ứng cử viên mã modulo:

int modulo_Euclidean(int a, int b) {
  int m = a % b;
  if (m < 0) {
    // m += (b < 0) ? -b : b; // avoid this form: it is UB when b == INT_MIN
    m = (b < 0) ? m - b : m + b;
  }
  return m;
}

Lưu ý về dấu phẩy động double fmod(double x, double y):, mặc dù được gọi là "fmod", nó không giống với "mod" phân chia Euclide, nhưng tương tự như phần còn lại của số nguyên C:

Các fmod hàm tính phần còn lại của dấu phẩy động x/y. C11dr §.12.12.10.1 2

fmod( 7,  3) -->  1.0  
fmod( 7, -3) -->  1.0  
fmod(-7,  3) --> -1.0  
fmod(-7, -3) --> -1.0   

Định hướng : C cũng có một hàm có tên tương tự double modf(double value, double *iptr), chia giá trị đối số thành các phần tách rời và phân số, mỗi phần có cùng loại và ký hiệu là đối số. Điều này ít liên quan đến cuộc thảo luận "mod" ở đây ngoại trừ sự giống nhau về tên.


1 Trước C99, định nghĩa của C %vẫn là phần còn lại từ phân chia, nhưng sau đó /cho phép các chỉ tiêu âm làm tròn xuống thay vì "cắt ngắn về 0". Xem tại sao bạn nhận được các giá trị khác nhau cho phép chia số nguyên trong C89? . Do đó, với một số biên dịch trước C99, %mã có thể hoạt động giống như "mod" phân chia Euclide. Ở trên modulo_Euclidean()sẽ làm việc với phần còn lại của trường cũ thay thế này quá.


1
Để thực hiện chức năng phân chia và mô đun Euclide trong C, hãy xem Phân chia và mô đun cho các nhà khoa học máy tính . Nó có thể chạy nhanh hơn nếu bạn chỉ biết cổ tức của mình có thể âm, nhưng số chia của bạn luôn dương: godbolt.org/g/63UqJo . Liên quan: một câu hỏi x86 asm yêu cầu modulo không âm
Peter Cordes

Định nghĩa thông thường của toán tử modulo giống như:
Mike Housky

2

Modulus, trong số học mô-đun như bạn đang đề cập, là giá trị còn lại hoặc giá trị còn lại sau khi phân chia số học. Điều này thường được gọi là phần còn lại. % chính thức là toán tử còn lại trong C / C ++. Thí dụ:

7 % 3 = 1  // dividend % divisor = remainder

Những gì còn lại để thảo luận là làm thế nào để xử lý đầu vào tiêu cực cho hoạt động% này. C và C ++ hiện đại tạo ra giá trị còn lại đã ký cho hoạt động này trong đó dấu hiệu của kết quả luôn khớp với đầu vào cổ tức mà không liên quan đến dấu hiệu của đầu vào ước số.


1

Trong C và C ++ và nhiều ngôn ngữ, %phần còn lại KHÔNG phải là toán tử mô đun.

Ví dụ trong hoạt động -21 / 4, phần nguyên là -5và phần thập phân là -.25. Phần còn lại là phần phân số nhân với số chia, nên phần còn lại của chúng ta là -1. JavaScript sử dụng toán tử còn lại và xác nhận điều này

console.log(-21 % 4 == -1);

Toán tử mô đun giống như bạn có "đồng hồ". Hãy tưởng tượng một vòng tròn với các giá trị 0, 1, 2 và 3 tại các vị trí 12 giờ, 3 giờ, 6 giờ và 9 giờ tương ứng. Bước thời gian thương lượng xung quanh đồng hồ thông minh đưa chúng ta đến kết quả của hoạt động mô đun của chúng tôi, hoặc, trong ví dụ của chúng tôi với thương số âm, ngược chiều kim đồng hồ, mang lại 3.

Lưu ý: Modulus luôn có cùng dấu với ước số và phần còn lại cùng dấu với thương số. Thêm ước số và phần dư khi phần còn lại ít nhất một là âm mang lại mô đun.


-2

Trong toán học, kết quả của phép toán modulo là phần còn lại của phép chia Euclide. Tuy nhiên, các quy ước khác là có thể. Máy tính và máy tính có nhiều cách lưu trữ và biểu diễn số khác nhau; do đó định nghĩa của họ về hoạt động modulo phụ thuộc vào ngôn ngữ lập trình và / hoặc phần cứng cơ bản.

 7 modulo  3 -->  1  
 7 modulo -3 --> -2 
-7 modulo  3 -->  2  
-7 modulo -3 --> -1 

2
Bộ phận wiki Euclide khẳng định 0 ≤ r < |b|có nghĩa là phần còn lại hay còn gọi là "hoạt động modulo". luôn luôn ít nhất là 0. Bạn định nghĩa gì khi sử dụng kết quả đó trong -2 và -1?
chux - Phục hồi Monica

thưa ngài, tôi không có nhưng tôi chỉ google 7 modulo -3 -> -2 .and.-7 modulo -3 -> -1 hãy giải thích cho ông tại sao điều này xảy ra
shub sharma

1
Google sử dụng một định nghĩa khác về modulo (modulo đã ký?) So với phân chia Wiki Euclide (như được mô tả bởi Raymond T. Boute). Điều này thảo luận về sự khác biệt nhiều hơn. Đạo đức của câu chuyện: a%ba modulo bcó cùng ý nghĩa khi a,btích cực. C99 định nghĩa %chính xác với các giá trị âm. C gọi đây là "phần còn lại". "Modulo" có nhiều định nghĩa khác nhau trên thế giới liên quan đến các giá trị âm. C spec chỉ sử dụng "modulo" trong bối cảnh các số dương.
chux - Tái lập lại
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.