Какая разница между "модом" и "остатком"?

Мой друг сказал, что между "модом" и "остатком" существуют различия.

Если да, то каковы эти различия в C и С++? "%" Означает "mod" или "rem" в C?

Ответ 1

Существует разность между модулем и остатком. Например:

-21 mod 4 есть 3, потому что -21 + 4 x 6 есть 3.

Но -21, деленный на 4, дает -5 с остатком -1.

Для положительных значений нет разницы.

Ответ 2

Does '%' mean either "mod" or "rem" in C?

В Си % является остатком1.

..., результатом оператора / является алгебраическое частное с любой отброшенной дробной частью... (Это часто называют "усечением до нуля".) C11dr §6.5.5 6

Операнды оператора % должны иметь целочисленный тип. C11dr §6.5.5 2

Результатом оператора / является частное от деления первого операнда на второй; Результатом оператора % является остаток... C11dr §6.5.5 5


Какая разница между "мод" и "остаток"?

C не определяет "mod", такой как функция целочисленного модуля, используемая в евклидовом делении или в другом модуле. "Евклидов мод" отличается от операции C 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:

The fmodfunctions compute the floating-point remainder of 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() будет работать и с этим альтернативным остатком старой школы.

Ответ 3

Модуль, в модульной арифметике, как вы говорите, является значением, оставшимся или оставшимся после арифметического деления. Это обычно называют остатком. % формально является оператором остатка в C/С++. Пример:

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

Что осталось для обсуждения, так это то, как относиться к отрицательным вкладам в эту% -ную операцию. Современные C и С++ производят знаковое значение остатка для этой операции, где знак результата всегда соответствует входному значению без учета знака входа делителя.

Ответ 4

В C и C++ и во многих языках % - это остаток, а не оператор модуля.

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

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

Ответ 5

В математике результатом операции по модулю является остальная часть евклидова деления. Однако возможны другие соглашения. Компьютеры и калькуляторы имеют различные способы хранения и представления чисел; поэтому их определение операции по модулю зависит от языка программирования и/или от базового оборудования.

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