Quando você divide dois inteiros, o resultado é sempre um inteiro. Por exemplo, o resultado de 7/3 é 2. Para determinar o restante de 7/3, use o operador de resto ( % ).
int a = 5;
int b = 3;
int div = a / b; //quotient is 1int mod = a % b; //remainder is 2
% retorna o resto, não o módulo (como você indicou). Eles não são a mesma coisa e podem causar problemas ao lidar com casos incomuns (por exemplo, índices negativos). No entanto, ele pode ser usado como o operador de módulo quando apenas procurando, por exemplo, a cada 10 iterações de um indexador fracamente positivo. Talvez você possa explicar como calcular o módulo real?
Cor_Blimey
1
É verdade, eu li postagens como esta e tive problemas em meu aplicativo :)
apocalipse
1
... Qual é exatamente o sentido de declarar ae bse você não vai usá-los? : D
leviathanbadger
1
Talvez o usuário estivesse procurando (como eu) por uma função DivRem, então a questão pode não ser tão trivial quanto parece à primeira vista. Obrigado @danodonovan
Tancredi
1
A resposta não é tão simples quanto afirma esta resposta, como outros também apontaram, e pode levar a erros difíceis de depurar. Consulte /programming/10065080/mod-explanation
Esta deve ser a resposta correta em minha opinião, porque fornece o quociente E o resto em uma função. Não tenho certeza de qual abordagem tem melhor desempenho (usando "a / b" para obter o quociente e "a% b" para obter o resto ou Math.DivRem), mas essa abordagem certamente é muito mais agradável de ler (no meu caso, preciso saber o quociente e o restante) - obrigado!
Igor
2
@Igor obrigado, quando a pergunta original foi respondida esta função não existia! No entanto, a existência da função faz com que o comentário do as-cii sobre a verificação da documentação pareça um pouco bobo .... :)
danodonovan
6
Apenas para evitar confusão, Math.DivRemnão calcula div e mod em uma operação. É apenas uma função auxiliar e seu código fonte é exatamente: public static int DivRem(int a, int b, out int result) { result = a%b; return a/b; }.
NightElfik
9
@NightElfik A implementação pode mudar no futuro, e é mais fácil para o tempo de execução identificar uma chamada de método para otimização do que disjunta dive reminstruções
kbolino
6
@kbolino Isso é uma grande previsão, uma vez que tenha mudado , pelo menos em .NET Core, dividir e subtrair. E há mais otimizações planejadas no RyuJIT para usar uma única instrução x86 div, embora reconheço que as alterações JIT também devem detectar os operadores %e /se usadas individualmente.
Portanto, você pode lançar o seu próprio, embora seja MUITO mais lento do que o operador% integrado:
publicstaticintMod(int a, int n)
{
return a - (int)((double)a / n) * n;
}
Edit: uau, falei mal aqui originalmente, obrigado @joren por me pegar
Agora estou contando com o fato de que division + cast-to-int em C # é equivalente a Math.Floor(isto é, elimina a fração), mas uma implementação "verdadeira" seria algo como:
publicstaticintMod(int a, int n)
{
return a - (int)Math.Floor((double)a / n) * n;
}
Na verdade, você pode ver as diferenças entre% e "módulo verdadeiro" com o seguinte:
var modTest =
from a in Enumerable.Range(-3, 6)
from b in Enumerable.Range(-3, 6)
where b != 0let op = (a % b)
let mod = Mod(a,b)
let areSame = op == mod
selectnew
{
A = a,
B = b,
Operator = op,
Mod = mod,
Same = areSame
};
Console.WriteLine("A B A%B Mod(A,B) Equal?");
Console.WriteLine("-----------------------------------");
foreach (var result in modTest)
{
Console.WriteLine(
"{0,-3} | {1,-3} | {2,-5} | {3,-10} | {4,-6}",
result.A,
result.B,
result.Operator,
result.Mod,
result.Same);
}
"Agora estou contando com o fato de que a divisão inteira em C # é equivalente a Math.Floor (ou seja, elimina a fração)" - Mas não é. A divisão inteira gira em direção a zero, Math.Floor gira em direção ao infinito negativo.
Joren
@Joren Desculpe, mas não - tente executar isto: Enumerable.Range(0, 10).Select(x => (double)x / 10.0).Select(x => (int)x).ToList().ForEach(x => Console.WriteLine(x));- todos os 0
JerKimball
2
Em primeiro lugar, estou falando sobre divisão inteira . O que acontece se você fizer uma divisão de ponto flutuante e, em seguida, converter para inteiro é irrelevante (embora forneça o mesmo resultado). Em segundo lugar, não sei por que você esperaria que inteiros entre 0 e 9 fornecessem qualquer coisa diferente de 0 depois de dividir por 10 e truncar para a parte inteira. Se isso resultou em 1 que seriam arredondamento longe de zero ou em direção positiva infinito. Terceiro, não há nenhuma diferença entre arredondar para zero e arredondar para infinito negativo para números positivos, portanto, você nem mesmo está abordando o problema.
Joren
Math.Floor(-10.0 / 3.0)e não-10 / 3 são a mesma coisa.
Joren
@joren ah, vejo a desconexão aqui - não, não estou executando a divisão inteira , estou executando a divisão dupla e, em seguida, convertendo o resultado para um número inteiro - muito diferente.
%
operador é não o operador módulo em C #.Respostas:
Antes de fazer perguntas desse tipo, verifique a documentação do MSDN .
int a = 5; int b = 3; int div = a / b; //quotient is 1 int mod = a % b; //remainder is 2
fonte
a
eb
se você não vai usá-los? : DTambém há
Math.DivRem
quotient = Math.DivRem(dividend, divisor, out remainder);
fonte
Math.DivRem
não calcula div e mod em uma operação. É apenas uma função auxiliar e seu código fonte é exatamente:public static int DivRem(int a, int b, out int result) { result = a%b; return a/b; }
.div
erem
instruções%
e/
se usadas individualmente.Fato engraçado!
A operação de 'módulo' é definida como:
Ref: Aritmética Modular
Portanto, você pode lançar o seu próprio, embora seja MUITO mais lento do que o operador% integrado:
public static int Mod(int a, int n) { return a - (int)((double)a / n) * n; }
Edit: uau, falei mal aqui originalmente, obrigado @joren por me pegar
Agora estou contando com o fato de que division + cast-to-int em C # é equivalente a
Math.Floor
(isto é, elimina a fração), mas uma implementação "verdadeira" seria algo como:public static int Mod(int a, int n) { return a - (int)Math.Floor((double)a / n) * n; }
Na verdade, você pode ver as diferenças entre% e "módulo verdadeiro" com o seguinte:
var modTest = from a in Enumerable.Range(-3, 6) from b in Enumerable.Range(-3, 6) where b != 0 let op = (a % b) let mod = Mod(a,b) let areSame = op == mod select new { A = a, B = b, Operator = op, Mod = mod, Same = areSame }; Console.WriteLine("A B A%B Mod(A,B) Equal?"); Console.WriteLine("-----------------------------------"); foreach (var result in modTest) { Console.WriteLine( "{0,-3} | {1,-3} | {2,-5} | {3,-10} | {4,-6}", result.A, result.B, result.Operator, result.Mod, result.Same); }
Resultados:
A B A%B Mod(A,B) Equal? ----------------------------------- -3 | -3 | 0 | 0 | True -3 | -2 | -1 | -1 | True -3 | -1 | 0 | 0 | True -3 | 1 | 0 | 0 | True -3 | 2 | -1 | 1 | False -2 | -3 | -2 | -2 | True -2 | -2 | 0 | 0 | True -2 | -1 | 0 | 0 | True -2 | 1 | 0 | 0 | True -2 | 2 | 0 | 0 | True -1 | -3 | -1 | -1 | True -1 | -2 | -1 | -1 | True -1 | -1 | 0 | 0 | True -1 | 1 | 0 | 0 | True -1 | 2 | -1 | 1 | False 0 | -3 | 0 | 0 | True 0 | -2 | 0 | 0 | True 0 | -1 | 0 | 0 | True 0 | 1 | 0 | 0 | True 0 | 2 | 0 | 0 | True 1 | -3 | 1 | -2 | False 1 | -2 | 1 | -1 | False 1 | -1 | 0 | 0 | True 1 | 1 | 0 | 0 | True 1 | 2 | 1 | 1 | True 2 | -3 | 2 | -1 | False 2 | -2 | 0 | 0 | True 2 | -1 | 0 | 0 | True 2 | 1 | 0 | 0 | True 2 | 2 | 0 | 0 | True
fonte
Enumerable.Range(0, 10).Select(x => (double)x / 10.0).Select(x => (int)x).ToList().ForEach(x => Console.WriteLine(x));
- todos os 0Math.Floor(-10.0 / 3.0)
e não-10 / 3
são a mesma coisa.A divisão é realizada usando o
/
operador:A divisão do módulo é feita usando o
%
operador:fonte
Leia dois inteiros do usuário. Em seguida, calcule / exiba o restante e o quociente,
// When the larger integer is divided by the smaller integer Console.WriteLine("Enter integer 1 please :"); double a5 = double.Parse(Console.ReadLine()); Console.WriteLine("Enter integer 2 please :"); double b5 = double.Parse(Console.ReadLine()); double div = a5 / b5; Console.WriteLine(div); double mod = a5 % b5; Console.WriteLine(mod); Console.ReadLine();
fonte