Мой друг сказал, что между "модом" и "остатком" существуют различия.
Если да, то каковы эти различия в 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
fmodfunctions 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