Qual é a diferença entre "mod" e "restante"?

133

Meu amigo disse que existem diferenças entre "mod" e "restante".

Se sim, quais são essas diferenças em C e C ++? '%' Significa "mod" ou "rem" em C?

songhir
fonte
2
Provavelmente está mal definido para operandos negativos.
Basile Starynkevitch 3/12/12
1
Eu não sou uma pessoa C :( por isso não posso responder a esta dentro da caixa de resposta Mas, por favor dê uma olhada nisso. Artigo :)
bonCodigo
1
% é restante. Detalhes da resposta aqui -> blogs.msdn.com/b/ericlippert/archive/2011/12/05/…
wim
1
A pergunta não significa nada até você definir com precisão o que os termos significam.
David Heffernan
14
@ David: a questão é sobre o significado dos termos. Se você diz que a pergunta não tem significado, apesar de várias pessoas a entenderem da maneira que o questionador pretendia, acho que você precisa ser mais específico sobre o que quer dizer com a palavra "dizer" ;-)
Steve Jessop

Respostas:

140

Há uma diferença entre o módulo e o restante. Por exemplo:

-21mod 4é 3porque -21 + 4 x 6é 3.

Mas -21dividido por 4-5com um resto de -1.

Para valores positivos, não há diferença.

David Schwartz
fonte
22
% significa rem em C.
banuj
22
@ Jinxiao: em C89, era definido pela implementação: %era sempre o restante, mas também poderia ser o módulo (ou seja, sempre positivo), porque em C89 a divisão inteira foi permitida para arredondar para o infinito negativo em vez de para 0. Então, em C89, -5 / 2poderia estar -2com o restante -1, ou -3com o restante 1, a implementação apenas precisava documentar qual. O C99 removeu a flexibilidade, então agora -5 / 2é sempre -2.
Steve Jessop
2
Na verdade, não está claro o que é módulo. Parece haver muitas definições diferentes, dependendo do contexto e da linguagem. Veja o artigo da wikipedia sobre modulo_operation. Em alguns contextos, é realmente o mesmo que o restante.
Rudy Velthuis
9
Alguém pode explicar as etapas do primeiro cálculo? Como -21mod 4é 3? Por que o cálculo é -21 + 4 x 6?
Oz Edri
13
@OzEdri Para obter algum número mod 4, você adicionar o que inteiro múltiplo de 4 é preciso para obter um número entre 0 e 3. Para -21, esse inteiro é 6 porque -21 + 4 x 6é entre 0 e 3.
David Schwartz
47

'%' Significa "mod" ou "rem" em C?

Em C, %é o restante 1 .

..., o resultado do /operador é o quociente algébrico com qualquer parte fracionária descartada ... (Isso geralmente é chamado de "truncamento em direção a zero"). C11dr §6.5.5 6

Os operandos do %operador devem ter um tipo inteiro. C11dr §6.5.5 2

O resultado do /operador é o quociente da divisão do primeiro operando pelo segundo; o resultado do %operador é o restante ... C11dr §6.5.5 5


Qual é a diferença entre "mod" e "restante"?

C não define "mod", como a função de módulo inteiro usada na divisão euclidiana ou outro módulo . O "mod euclidiano" difere da a%boperação de C quando aé negativo.

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

Módulo como divisão euclidiana

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

Código do módulo candidato:

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

Nota sobre o ponto flutuante: double fmod(double x, double y)apesar de chamado "fmod", não é o mesmo que divisão euclidiana "mod", mas é semelhante ao restante C inteiro:

As fmod funções calculam o restante de ponto flutuante 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   

Desambiguação : C também possui uma função nomeada semelhante, double modf(double value, double *iptr)que divide o valor do argumento em partes integrais e fracionárias, cada uma com o mesmo tipo e sinal que o argumento. Isso tem pouco a ver com a discussão "mod" aqui, exceto a similaridade de nomes.


1 Antes de C99, a definição de C %ainda era o restante da divisão, mas /permitiu quocientes negativos arredondarem para baixo em vez de "truncamento em direção a zero". Consulte Por que você obtém valores diferentes para a divisão inteira no C89? . Assim, com alguma compilação pré-C99, o %código pode agir exatamente como a divisão euclidiana "mod". O exposto acima modulo_Euclidean()também funcionará com este restante alternativo da velha escola.

chux - Restabelecer Monica
fonte
1
Para implementar a divisão euclidiana e as funções de módulo em C, consulte Divisão e módulo para cientistas da computação . Ele pode correr mais rápido se você souber que apenas seu dividendo pode ser negativo, mas seu divisor é sempre positivo: godbolt.org/g/63UqJo . Relacionados: uma questão em x86 ASM pedindo modulo não negativo
Peter Cordes
A definição usual do operador módulo é mais como:
Mike Housky
2

Módulo, na aritmética modular, como você está se referindo, é o valor que resta ou o valor restante após a divisão aritmética. Isso é conhecido como restante. % é formalmente o operador restante em C / C ++. Exemplo:

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

O que resta para discussão é como tratar entradas negativas para essa operação%. C e C ++ modernos produzem um valor restante assinado para esta operação em que o sinal do resultado sempre corresponde à entrada de dividendos sem levar em conta o sinal da entrada do divisor.

user487158
fonte
1

Em C e C ++ e em muitas linguagens, %o restante NÃO é o operador de módulo.

Por exemplo, na operação, -21 / 4a parte inteira é -5e a parte decimal é -.25. O restante é a parte fracionária vezes o divisor, portanto, o restante é -1. JavaScript usa o operador restante e confirma isso

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

O operador do módulo é como se você tivesse um "relógio". Imagine um círculo com os valores 0, 1, 2 e 3 nas posições de 12, 3, 6 e 9, respectivamente. Passar o quociente o tempo todo no sentido horário nos leva ao resultado de nossa operação de módulo ou, em nosso exemplo, com um quociente negativo no sentido anti-horário, produzindo 3.

Nota: O módulo é sempre o mesmo sinal que o divisor e o restante é o mesmo sinal que o quociente. Adicionar o divisor e o restante quando o restante pelo menos um for negativo gera o módulo.

theEpsilon
fonte
-2

Em matemática, o resultado da operação do módulo é o restante da divisão euclidiana. No entanto, outras convenções são possíveis. Computadores e calculadoras têm várias maneiras de armazenar e representar números; portanto, sua definição da operação do módulo depende da linguagem de programação e / ou do hardware subjacente.

 7 modulo  3 -->  1  
 7 modulo -3 --> -2 
-7 modulo  3 -->  2  
-7 modulo -3 --> -1 
shub sharma
fonte
2
A divisão euclidiana do wiki afirma o 0 ≤ r < |b|que significa o restante, também conhecido como "operação de módulo". é sempre pelo menos 0. Que definição você está usando que resulta em -2 e -1?
Chux - Reintegrar Monica
Senhor, eu não não, mas eu só google 7 modulo -3 -> -2 .and.-7 modulo -3 -> -1 explique senhor por que isso aconteceu
shub Sharma
1
O Google usa uma definição diferente de módulo (módulo assinado?) Que a divisão euclidiana do Wiki (conforme descrito por Raymond T. Boute). Isso discute as diferenças mais. Moral da história: a%be a modulo btem o mesmo significado quando a,bpositivo. C99 define %precisamente com valores negativos. C chama isso de "resto'. 'Modulo' tem várias definições no mundo em matéria de valores negativos C especificação só usa. 'Módulo' no contexto de números positivos.
Chux - Reintegrar Monica