¿Estoy haciendo mal el módulo? Porque en Java -13 % 64
se supone que debe evaluarse, -13
pero obtengo 51
.
%
es un operador de resto.
¿Estoy haciendo mal el módulo? Porque en Java -13 % 64
se supone que debe evaluarse, -13
pero obtengo 51
.
%
es un operador de resto.
Respuestas:
Se utilizan ambas definiciones de módulo de números negativos: algunos lenguajes utilizan una definición y otros la otra.
Si desea obtener un número negativo para las entradas negativas, puede usar esto:
int r = x % n;
if (r > 0 && x < 0)
{
r -= n;
}
Del mismo modo, si estuviera utilizando un idioma que devuelve un número negativo en una entrada negativa y preferiría positivo:
int r = x % n;
if (r < 0)
{
r += n;
}
x % y
, A) si x
es negativo, el resto es negativo, es decir x % y == -(-x % y)
. B) el signo de y
no tiene ningún efecto, es decirx % y == x % -y
Dado que "matemáticamente" ambos son correctos:
-13 % 64 = -13 (on modulus 64)
-13 % 64 = 51 (on modulus 64)
Una de las opciones tuvo que ser elegida por los desarrolladores del lenguaje Java y eligieron:
el signo del resultado es igual al signo del dividendo.
Lo dice en las especificaciones de Java:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3
-13 % 64 = 51
cuando estaba esperando -13
?".
int result = (-5) % 3;
da -2. int result = (-3) % 5;
da -3. En general, int result = (-a) % b;
da la respuesta correcta cuando | -a | > b. Para obtener el resultado adecuado cuando | -a | <b debemos envolver el divisor. int result = ((-a) % b) + b;
para negativo a o int result = (((-a) % b) + b) % b;
para positivo o negativo a
Su resultado es incorrecto para Java. Proporcione algo de contexto sobre cómo llegó a él (su programa, implementación y versión de Java).
De la especificación del lenguaje Java
15.17.3 Operador restante%
[...]
La operación restante para operandos que son enteros después de la promoción numérica binaria (§5.6.2) produce un valor de resultado tal que (a / b) * b + (a% b) es igual a a.
15.17.2 Operador de división / división
[...]
entera se redondea hacia 0.
Dado que / se redondea hacia cero (resultando en cero), el resultado de% debería ser negativo en este caso.
int result = (-5) % 3;
da -2 int result = (-3) % 5;
da -3 En general, int result = (-a) % b;
da la respuesta correcta cuando | -a | > b Para obtener el resultado adecuado cuando | -a | <b debemos envolver el divisor. int result = ((-a) % b) + b;
para negativo a o int result = (((-a) % b) + b) % b;
para positivo o negativo a.
(-3) % 5
el resultado correcto según la definición es -3
, y una implementación correcta de Java debería producir ese resultado.
(-3)%5
hecho da -3
, y si queremos el resto positivo debemos agregarle 5, y entonces el resultado será2
puedes usar
(x % n) - (x < 0 ? n : 0);
((x % k) + k) % k
. (Aunque el tuyo probablemente sea más legible.)
[0, sign(divisor) * divisor)
lugar de [0, sign(dividend) * divisor)
.
Su respuesta está en wikipedia: operación de módulo
Dice que en Java la operación de signo en módulo es la misma que la de dividendo. y dado que estamos hablando del resto de la operación de división está bien, devuelve -13 en su caso, ya que -13/64 = 0. -13-0 = -13.
EDITAR: Lo siento, entendí mal tu pregunta ... Tienes razón, java debería dar -13. ¿Puede proporcionar más código circundante?
La aritmética de módulo con operandos negativos la define el diseñador del lenguaje, quien podría dejarlo en manos de la implementación del lenguaje, quien podría diferir la definición a la arquitectura de la CPU.
No pude encontrar una definición de lenguaje Java.
Gracias Ishtar, la especificación del lenguaje Java para el operador restante% dice que el signo del resultado es el mismo que el signo del numerador.
x = x + m = x - m
en módulo m
.
así que -13 = -13 + 64
en módulo 64
y -13 = 51
en módulo 64
.
Supongamos Z = X * d + r
, si 0 < r < X
entonces en división Z/X
llamamos r
al resto.
Z % X
devuelve el resto de Z/X
.
La función mod se define como la cantidad por la cual un número excede el múltiplo entero más grande del divisor que no es mayor que ese número. Entonces en tu caso de
-13 % 64
el mayor múltiplo entero de 64 que no exceda -13 es -64. Ahora, cuando resta -13 de -64 es igual a 51-13 - (-64) = -13 + 64 = 51
En mi versión de Java JDK 1.8.0_05 -13% 64 = -13
podría intentar -13- (int (-13/64)) en otras palabras, hacer la división en un número entero para deshacerse de la parte de la fracción y luego restar del numerador Entonces, el numerador- (int (numerador / denominador)) debería dar el correcto resto y signo
En las últimas versiones de Java obtienes -13%64 = -13
. La respuesta siempre tendrá signo de numerador.
De acuerdo con la sección 15.17.3 de la JLS, "La operación de resto para operandos que son enteros después de la promoción numérica binaria produce un valor de resultado tal que (a / b) * b + (a% b) es igual a a. Esta identidad se mantiene incluso en el caso especial de que el dividendo sea el entero negativo de mayor magnitud posible para su tipo y el divisor sea -1 (el resto es 0) ".
Espero que ayude.
No creo que Java devuelva 51 en este caso. Estoy ejecutando Java 8 en una Mac y obtengo:
-13 % 64 = -13
Programa:
public class Test {
public static void main(String[] args) {
int i = -13;
int j = 64;
System.out.println(i % j);
}
}