Мой друг сказал, что между "модом" и "остатком" существуют различия.
Если да, то каковы эти различия в C и С++? "%" Означает "mod" или "rem" в C?
Мой друг сказал, что между "модом" и "остатком" существуют различия.
Если да, то каковы эти различия в C и С++? "%" Означает "mod" или "rem" в C?
Существует разность между модулем и остатком. Например:
-21
mod 4
есть 3
, потому что -21 + 4 x 6
есть 3
.
Но -21
, деленный на 4
, дает -5
с остатком -1
.
Для положительных значений нет разницы.
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
fmod
functions compute the floating-point remainder ofx/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()
будет работать и с этим альтернативным остатком старой школы.
Модуль, в модульной арифметике, как вы говорите, является значением, оставшимся или оставшимся после арифметического деления. Это обычно называют остатком. % формально является оператором остатка в C/С++. Пример:
7 % 3 = 1 // dividend % divisor = remainder
Что осталось для обсуждения, так это то, как относиться к отрицательным вкладам в эту% -ную операцию. Современные C и С++ производят знаковое значение остатка для этой операции, где знак результата всегда соответствует входному значению без учета знака входа делителя.
В C и C++ и во многих языках %
- это остаток, а не оператор модуля.
Например, в операции -21 / 4
целочисленная часть - -5
, а десятичная часть - -.25
. Остаток - это дробная часть, умноженная на делитель, поэтому наш остаток - -1
. JavaScript использует оператор остатка и подтверждает это
console.log(-21 % 4 == -1);
В математике результатом операции по модулю является остальная часть евклидова деления. Однако возможны другие соглашения. Компьютеры и калькуляторы имеют различные способы хранения и представления чисел; поэтому их определение операции по модулю зависит от языка программирования и/или от базового оборудования.
7 modulo 3 --> 1
7 modulo -3 --> -2
-7 modulo 3 --> 2
-7 modulo -3 --> -1