Como o java faz cálculos de módulo com números negativos?

Estou fazendo o módulo errado? Porque em Java -13 % 64 deve ser avaliado como -13 mas eu recebo 51 .

Ambas as definições de módulo de números negativos estão em uso – algumas linguagens usam uma definição e outras.

Se você quiser obter um número negativo para inputs negativas, então você pode usar isto:

 int r = x % n; if (r > 0 && x < 0) { r -= n; } 

Da mesma forma, se você estivesse usando um idioma que retorna um número negativo em uma input negativa e preferiria positivo:

 int r = x % n; if (r < 0) { r += n; } 

Desde “matematicamente” ambos estão corretos:

 -13 % 64 = -13 (on modulus 64) -13 % 64 = 51 (on modulus 64) 

Uma das opções teve que ser escolhida pelos desenvolvedores de linguagem Java e eles escolheram:

o sinal do resultado é igual ao sinal do dividendo.

Diz nas especificações do Java:

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3

Você tem certeza de que está trabalhando em Java? porque Java dá -13% 64 = -13 como esperado. O sinal do dividendo!

Seu resultado está errado para o Java. Por favor, forneça algum contexto como você chegou a ele (seu programa, implementação e versão do Java).

Da especificação da linguagem Java

15.17.3 Operador de Restante%
[…]
A operação restante para operandos que são inteiros após a promoção numérica binária (§5.6.2) produz um valor de resultado tal que (a / b) * b + (a% b) é igual a a.

15.17.2 Operador da Divisão /
[…]
A divisão inteira é arredondada para 0.

Como / é arredondado para zero (resultando em zero), o resultado de% deve ser negativo neste caso.

você pode usar

 (x % n) - (x < 0 ? n : 0); 

Sua resposta está na wikipedia: modulo operation

Ele diz que, em Java, a operação do sinal no módulo é a mesma que a do dividendo. e desde que estamos falando sobre o resto da operação de divisão é muito bem, que ele retorna -13 no seu caso, desde -13/64 = 0. -13-0 = -13.

EDIT: Desculpe, entendeu mal sua pergunta … Você está certo, java deve dar -13. Você pode fornecer mais código ao redor?

A aritmética modular com operandos negativos é definida pelo projetista da linguagem, que pode deixar para a implementação da linguagem, que pode adiar a definição para a arquitetura da CPU.

Não consegui encontrar uma definição de linguagem Java.
Obrigado Ishtar, Java Language Specification para o operador Restante% diz que o sinal do resultado é o mesmo que o sinal do numerador.

Para superar isso, você pode adicionar 64 (ou qualquer que seja sua base de módulo) ao valor negativo até que seja positivo

 int k = -13; int modbase = 64; while (k < 0) { k += modbase; } int result = k % modbase; 

O resultado ainda estará na mesma class de equivalência.

x = x + m = x - m em módulo m .
então -13 = -13 + 64 no módulo 64 e -13 = 51 no módulo 64 .
suponha que Z = X * d + r , se 0 < r < X então na divisão Z/X nós chamamos r o resto.
Z % X retorna o restante de Z/X

A function mod é definida como o valor pelo qual um número excede o maior múltiplo inteiro do divisor que não é maior que esse número. Então, no seu caso de

 -13 % 64 

o maior múltiplo inteiro de 64 que não exceda -13 é -64. Agora, quando você subtrai -13 de -64, é igual a 51 -13 - (-64) = -13 + 64 = 51

Na minha versão do Java JDK 1.8.0_05 -13% 64 = -13

você poderia tentar -13- (int (-13/64)) em outras palavras, fazer uma divisão de divisão em um inteiro para se livrar da parte fracionária e então subtrair do numerador. Assim, o numerador- (int (numerador / denominador)) deve fornecer o valor correto. restante e assinar

Nas últimas versões do Java, você obtém -13%64 = -13 . A resposta sempre terá sinal do numerador.

De acordo com a seção 15.17.3 do JLS, “A operação restante para operandos que são inteiros após a promoção numérica binária produz um valor de resultado tal que (a / b) * b + (a% b) é igual a a. no caso especial, que o dividendo é o inteiro negativo de maior magnitude possível para o seu tipo e o divisor é -1 (o restante é 0). ”

Espero que ajude.

Eu não acho que o Java retorne 51 neste caso. Estou executando o Java 8 em um Mac e recebo:

 -13 % 64 = -13 

Programa:

 public class Test { public static void main(String[] args) { int i = -13; int j = 64; System.out.println(i % j); } }