¿Cómo hace Java cálculos de módulo con números negativos?


¿Estoy haciendo mal el módulo? Porque en Java -13 % 64 se supone que evalúe a -13 pero obtengo 51.

Author: CharlesB, 2010-12-10

14 answers

Ambas definiciones de módulo de números negativos están en uso - algunos lenguajes usan una definición y otros la otra.

Si desea obtener un número negativo para entradas negativas, puede usar esto:

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

Del mismo modo, si estuviera utilizando un lenguaje que devuelve un número negativo en una entrada negativa y preferiría positivo:

int r = x % n;
if (r < 0)
{
    r += n;
}
 97
Author: Mark Byers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-09 23:18:17

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

 68
Author: Caner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-19 08:31:20

¿Estás seguro de que estás trabajando en Java? porque Java da -13% 64 = -13 como se esperaba. ¡El signo del dividendo!

 19
Author: Keyxeq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-09 10:44:41

El resultado es incorrecto para Java. Por favor, proporcione algún contexto de 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 de Resto %
[...]
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 /
[...]
Rondas de división entera hacia 0.

Dado que / se redondea hacia cero (lo que resulta en cero), el resultado de % debe ser negativo en este caso.

 14
Author: starblue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-11 21:22:55

Puede usar

(x % n) - (x < 0 ? n : 0);
 5
Author: ruslik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-27 14:54:39

Su respuesta está en wikipedia: operación modulo

Dice, que en Java el signo en la operación de módulo es el mismo que el de dividendo. y ya que estamos hablando sobre el resto de la operación de división está bien, que devuelve -13 en su caso, ya -13/64 = 0. -13-0 = -13.

EDITAR: Lo siento, malinterpreté tu pregunta...Tienes razón, Java debería dar -13. ¿Puede proporcionar más código circundante?

 3
Author: Nava Carmon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-09 22:06:02

La aritmética modulo con operandos negativos es definida por el diseñador del lenguaje, que podría dejarlo en manos de la implementación del lenguaje, que podría diferir la definición a la arquitectura de la CPU.

No pude encontrar una definición del 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.

 2
Author: wallyk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-05 08:30:43

Para superar esto, podría agregar 64 (o lo que sea su base de módulo) al valor negativo hasta que sea positivo

int k = -13;
int modbase = 64;

while (k < 0) {
    k += modbase;
}

int result = k % modbase;

El resultado seguirá estando en la misma clase de equivalencia.

 1
Author: Andreas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-09 22:07:19

x = x + m = x - m in modulus 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 la división Z/X llamamos r al resto.
Z % X devuelve el resto de Z/X.

 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-09 22:09:50

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. Así que en su caso de

-13 % 64

El múltiplo entero más grande de 64 que no exceda -13 es -64. Ahora, cuando restas -13 de -64 es igual a 51 -13 - (-64) = -13 + 64 = 51

 1
Author: Salman Paracha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-09 22:09:56

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 división fundido a un entero para deshacerse de la parte de la fracción luego restar del numerador Así que numerador - (int (numerador/denominador)) debe dar el resto correcto & signo

 0
Author: Robert Green,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-12 02:00:14

En las últimas versiones de Java se obtiene -13%64 = -13. La respuesta siempre tendrá signo de numerador.

 0
Author: vsn harish rayasam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-23 15:41:09

De acuerdo con la sección 15.17.3 de la JLS, "La operación restante 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 es el entero negativo de mayor magnitud posible para su tipo y el divisor es -1 (el resto es 0)."

Espero que eso ayude.

 0
Author: kudesiaji,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-14 14:09:42

No creo que Java devuelva 51 en este caso. Estoy ejecutando Java 8 en un 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);
    }
}
 -1
Author: ceprateek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-23 15:38:42