En java cuando lo hagas
a % b
Si a es negativo, devolverá un resultado negativo, en lugar de ajustarse a b como debería. ¿Cuál es la mejor forma de solucionar este problema? La única forma en que puedo pensar es
a < 0 ? b + a : a % b
java
modulo
negative-number
fingir
fuente
fuente

Respuestas:
Se comporta como debería a% b = a - a / b * b; es decir, es el resto.
Puedes hacer (a% b + b)% b
Esta expresión funciona porque
(a % b)es necesariamente menor queb, sin importar siaes positivo o negativo. La sumabse ocupa de los valores negativos dea, ya que(a % b)es un valor negativo entre-by0,(a % b + b)es necesariamente menor queby positivo. El último módulo está ahí en caso de queafuera positivo al principio, ya que siaes positivo(a % b + b)se volvería más grande queb. Por lo tanto, lo(a % b + b) % bconvierte en más pequeño quebnuevamente (y no afecta losavalores negativos ).fuente
(a % b)es necesariamente menor queb(no importa siaes positivo o negativo), la sumabse encarga de los valores negativos dea, ya que(a % b)es menor queby menor que0,(a % b + b)es necesariamente menor queby positivo. El último módulo está ahí en caso de queafuera positivo para empezar, ya que siaes positivo(a % b + b)se volvería más grande queb. Por lo tanto, lo(a % b + b) % bconvierte en más pequeño quebnuevamente (y no afecta losavalores negativos ).a < 0, tal vez podría echar un vistazo)(a % b + b) % bse desglosa para valores muy grandes deayb. Por ejemplo, usara = Integer.MAX_VALUE - 1yb = Integer.MAX_VALUEdará-3como resultado, que es un número negativo, que es lo que quería evitar.whilesería más lento si realmente lo necesita, excepto que solo necesita un,ifen cuyo caso es más rápido.A partir de Java 8, puede usar Math.floorMod (int x, int y) y Math.floorMod (long x, long y) . Ambos métodos arrojan los mismos resultados que la respuesta de Peter.
fuente
floatodoubleargumentos. El operador binario Mod (%) también funciona con operandosfloatydouble.Para aquellos que aún no usan (o no pueden usar) Java 8, Guava vino al rescate con IntMath.mod () , disponible desde Guava 11.0.
Una advertencia: a diferencia de Math.floorMod () de Java 8, el divisor (el segundo parámetro) no puede ser negativo.
fuente
En teoría de números, el resultado siempre es positivo. Supongo que este no es siempre el caso en los lenguajes informáticos porque no todos los programadores son matemáticos. Mis dos centavos, lo consideraría un defecto de diseño del lenguaje, pero no puedes cambiarlo ahora.
= MOD (-4,180) = 176 = MOD (176, 180) = 176
porque 180 * (-1) + 176 = -4 lo mismo que 180 * 0 + 176 = 176
Usando el ejemplo del reloj aquí, http://mathworld.wolfram.com/Congruence.html , no diría que duration_of_time mod cycle_length es -45 minutos, diría que 15 minutos, aunque ambas respuestas satisfacen la ecuación base.
fuente
-1lugar de,n-1por ejemplo) entonces hágalo.Java 8 tiene
Math.floorMod, pero es muy lento (su implementación tiene múltiples divisiones, multiplicaciones y un condicional). Sin embargo, es posible que la JVM tenga un código auxiliar optimizado intrínseco, lo que lo aceleraría significativamente.La forma más rápida de hacer esto sin
floorModes como algunas otras respuestas aquí, pero sin ramas condicionales y solo una%operación lenta .Suponiendo que n es positivo y x puede ser cualquier cosa:
Los resultados cuando
n = 3:Si solo necesita una distribución uniforme entre
0yn-1y no el operador de mod exacto, yxlos suyos no se agrupan cerca0, lo siguiente será aún más rápido, ya que hay más paralelismo a nivel de instrucción y el%cálculo lento ocurrirá en paralelo con el otro partes ya que no dependen de su resultado.return ((x >> 31) & (n - 1)) + (x % n)Los resultados de lo anterior con
n = 3:Si la entrada es aleatoria en el rango completo de un int, la distribución de ambas soluciones será la misma. Si los grupos de entrada se acercan a cero, habrá muy pocos resultados
n - 1en la última solución.fuente
Aquí hay una alternativa:
Esto podría ser más rápido o no que la otra fórmula [(a% b + b)% b]. A diferencia de la otra fórmula, contiene una rama, pero usa una operación de módulo menos. Probablemente sea una victoria si la computadora puede predecir un <0 correctamente.
(Editar: se corrigió la fórmula).
fuente