Яка різниця між модом та рештою?


133

Мій друг сказав, що між "модом" та "залишком" є відмінності.

Якщо так, то які ті відмінності в C і C ++? Чи означає "%" або "mod", або "rem" в C?


2
Ймовірно, це неправильно визначено для негативних операндів.
Василь Старинкевич

1
Я не людина С :( тому я не можу реально відповісти на це у полі відповідей. Але, будь ласка, подивіться на цю статтю :)
bonCodigo

1
% - залишок. Деталі відповіді тут -> blogs.msdn.com/b/ericlippert/archive/2011/12/05/…
wim

1
Питання нічого не означає, поки ви точно не визначите, що означають терміни.
Девід Геффернан

14
@David: питання про значення термінів. Якщо ви говорите, що питання не має сенсу, незважаючи на те, що кілька людей розуміють його таким чином, як запитувальник мав намір, я вважаю, що ви повинні бути більш конкретними, що ви маєте на увазі під словом "означає" ;-)
Стів Джессоп

Відповіді:


140

Існує різниця між модулем і залишком. Наприклад:

-21мод 4тому, 3що -21 + 4 x 6є 3.

Але -21розділений на 4подає -5з залишком -1.

Для позитивних значень різниці немає.


22
% означає
залишок

22
@Jinxiao: в C89 це визначається реалізацією: %завжди був залишок, але це може також бути модулем (тобто завжди позитивно), так як в C89 ціле розподіл було дозволено круглий в сторону негативної нескінченності , а не в бік 0. Таким чином , в C89, -5 / 2може бути -2з залишком -1або -3з залишком 1, реалізація просто повинна була документувати який. C99 усунув гнучкість, тому зараз -5 / 2це завжди -2.
Стів Джессоп

2
Власне, не ясно, що таке модуль. Здається, існує багато різних визначень, залежно від контексту та мови. Дивіться статтю у wikipedia про modulo_operation. У деяких контекстах це фактично те саме, що і в решті.
Руді Вельтьюс

9
Чи може хтось пояснити кроки в першому розрахунку? Як -21мода 4це 3? Чому розрахунок -21 + 4 x 6?
Оз Едрі

13
@OzEdri Щоб отримати деяке число мод 4, ви додасте будь-яке ціле число, кратне 4, потрібно, щоб отримати число від 0 до 3. Для -21 це ціле число дорівнює 6, тому що -21 + 4 x 6знаходиться між 0 і 3.
Девід Шварц

47

Чи означає "%" або "mod", або "rem" в C?

В C %- залишок 1 .

..., результатом /оператора є алгебраїчний коефіцієнт, який відкидається дробовою частиною ... (Це часто називають "усіченням до нуля".) C11dr §6.5.5 6

Операнди %оператора мають цілий тип. C11dr §6.5.5 2

Результат /оператора - коефіцієнт від ділення першого операнда на другий; результат %оператора - залишок ... C11dr §6.5.5 5


Яка різниця між модом та рештою?

C не визначає "mod", такий як функція цілочисельного модуля, що використовується в евклідовому поділі або іншому модулі . "Евклідовий мод" відрізняється від роботи С, a%bколи aє негативним.

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

Модуло як евклідовий поділ

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

Модульний код кандидата:

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;
}

Зауважте про плаваючу крапку: double fmod(double x, double y)хоч і називається "fmod", це не те саме, що поділ Евкліда "mod", але схоже на цілу цілу кількість C:

Ці fmod функції обчислення з плаваючою точкою залишок x/y. C11dr §7.12.10.1 2

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

Розбіжність : C також має аналогічну названу функцію, double modf(double value, double *iptr)яка розбиває значення аргументу на цілісні та дробові частини, кожна з яких має той самий тип і знак, що і аргумент. Це мало спільного з обговоренням "мод" тут, крім схожості імен.


1 До C99 визначення C %все ще було залишком від поділу, але тоді /дозволяло негативним коефіцієнтам округлюватись, а не "усікання до нуля". Див. Чому ви отримуєте різні значення для цілого поділу в C89? . Таким чином, при деякій компіляції до C99 %код може діяти так само, як і евклідовий поділ "mod". Вищезгадане також modulo_Euclidean()буде працювати з цим альтернативним залишком старої школи.


1
Для реалізації функцій поділу та модуля Евкліда в С див. Розділ та модуль для вчених-комп'ютерів . Він може працювати швидше, якщо ви знаєте, що тільки ваш дивіденд може бути негативним, але ваш дільник завжди позитивний: godbolt.org/g/63UqJo . Пов’язано: запитання про x86 щодо запиту про негативний модуль
Пітер Кордес

Звичайне визначення оператора модуля більше нагадує:
Майк Госкі

2

Модуль у модульній арифметиці, як ви посилаєтесь, - це значення, що залишилося або залишилося значення після арифметичного поділу. Це зазвичай відоме як залишок. % формально залишається оператором C / C ++. Приклад:

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

Що залишається для обговорення - це як поводитися з негативними входами для цього% операції. Сучасні C і C ++ виробляють підписане залишкове значення для цієї операції, коли знак результату завжди відповідає входу дивідендів, не враховуючи ознаки вводу дільника.


1

В мовах C і C ++ та багатьох мовах, % - це залишок НЕ оператор модуля.

Наприклад, в операції -21 / 4ціла частина є, -5а десяткова частина - -.25. Залишок - це дробова частина, менша від дільника, тому наша решта є -1. JavaScript використовує оператор, що залишився, і підтверджує це

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

Оператор модуля такий, як у вас був "годинник". Уявіть собі коло зі значеннями 0, 1, 2 та 3 у положеннях 12 годин, 3 години, 6 годин та 9 годин відповідно. Крок коефіцієнта цілодобової годинникової стрілки орієнтується на результат нашої роботи з модулем або, у нашому прикладі, з від’ємним коефіцієнтом, проти годинникової стрілки, даючи 3.

Примітка: Модуль - це завжди той самий знак, що і дільник, а решта - той самий знак, що і коефіцієнт. Додавання дільника та решти, коли залишок хоча б одного від'ємний, дає модуль.


-2

У математиці результатом модульної операції є залишок евклідового поділу. Однак можливі й інші конвенції. Комп'ютери та калькулятори мають різні способи зберігання та представлення номерів; таким чином, їх визначення модульної роботи залежить від мови програмування та / або базового обладнання.

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

2
Підрозділ вікі евклідової стверджує , 0 ≤ r < |b|що означає залишок ака «операції по модулю.» завжди принаймні 0. Яке визначення ви використовуєте, що призводить до значень -2 і -1?
chux

сер, я не, але я просто google 7 modulo -3 -> -2 .and.-7 modulo -3 -> -1, будь ласка, поясніть, чому це сталося
shub sharma

1
Google використовує інше визначення модуля (підписаний модуль?), Ніж поділ Вікі Евкліда (як описав Реймонд Т. Буте). Тут більше обговорюються відмінності. Мораль розповіді: a%bі a modulo bмають те саме значення, коли a,bвони позитивні. C99 визначає %точно з від'ємними значеннями. C називає це "залишком". "Modulo" має різні визначення у світі щодо негативних значень. C spec використовує лише "modulo" в контексті додатних чисел.
chux - Відновити Моніку
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.