División entera y operación de módulo con operandos negativos en Python

Surgen preguntas cuando escribo estas expresiones en Python 3.3.0

-10 // 3 # -4 -10 % 3 # 2 10 // -3 # -4 10 % -3 # -2 -10 // -3 # 3 

Parece que toma el punto flotante aproximado (-3.33)? y se redondea de cualquier manera en la división entera, pero en la operación de módulo hace algo totalmente diferente. Parece que devuelve el rest +/- 1 y solo cambia el signo dependiendo de donde está el operando negativo. ¡Estoy completamente confundido, incluso después de revisar otras respuestas en este sitio! ¡Espero que alguien pueda explicarme esto también! El libro dice una pista: recuerda esta fórmula mágica a = (a // b) (b) + (a% b), pero eso no parece limpiar el agua para mí en absoluto.

-¡Gracias por adelantado!

Edit: esas son solo mis evaluaciones personales de lo que sucede (arriba), lo sé, ¡estoy completamente fuera!

La división de enteros solo está tomando el piso del número obtenido al final.

 10/3 -> floor(3.33) -> 3 -10/3 -> floor(-3.33) -> -4 

(¿Por qué pisos?)


La operación de módulo, por otro lado, está siguiendo la definición matemática .

  • Fórmula mágica: a = (a // b) * b + (a % b)
  • a: -10
  • b: 3
  • a // b: -4
  • a % b: 2

    Sustituir en fórmula mágica: -10 = -4 * 3 + 2 = -12 + 2 = -10

  • a: 10

  • b: -3
  • a // b: -4
  • a % b: -2

    En la fórmula mágica: 10 = -4 * -3 - 2 = 12 - 2 = 10

Así que la fórmula mágica parece ser correcta.

Si define a // b como floor(a / b) (que es), a % b debería ser a - floor(a / b) * b . Veamos:

  • a: -10
  • b: 3
  • a % b = a - floor(a / b) * b = -10 - floor(-3.33) * 3 = -10 + 4 * 3 = 2

El hecho de que a // b siempre esté anulada es bastante fácil de recordar (lea el primer enlace de Cthulhu, es una explicación del creador de Python). Para el negativo a en a % b … intente imaginar una tabla de números que comience en 0 y tenga b columnas:

 b = 3: 0 1 2 3 4 5 6 7 8 9 10 11 ... 

Si a es el número en una celda, a % b sería el número de la columna:

 aa % b _______________ 0 1 2 0 1 2 3 4 5 0 1 2 6 7 8 0 1 2 9 10 11 0 1 2 

Ahora extienda la tabla de nuevo en los negativos:

  aa % b __________________ -12 -11 -10 0 1 2 -9 -8 -7 0 1 2 -6 -5 -4 0 1 2 -3 -2 -1 0 1 2 0 1 2 0 1 2 3 4 5 0 1 2 6 7 8 0 1 2 9 10 11 0 1 2 

-10 % 3 seria 2 . La negativa a en a % b surgiría en este tipo de contexto. a % b con a % b negativo no aparece mucho.

Una regla simple: para a % b = c , si c no es cero, debe tener el mismo signo que b .

Y aplica la fórmula mágica:

10 % -3 = -2 => 10 // -3 = (10 - (-2)) / (-3) = -4

-10 % 3 = 2 => -10 // 3 = (-10 - 2) / 3 = -4

-10 % -3 = -1 => -10 // -3 = (-10 - (-1)) / (-3) = 3

OK, así que hice algunas excavaciones y creo que el problema no es Python, sino la función Modulo. Estoy basando esta respuesta en http://mathforum.org/library/drmath/view/52343.html

10% 3 Utiliza el múltiplo más alto de 3 que es MENOS DE 10. En este caso, 9. 10 – 9 = 1

-10% 3 hace lo mismo. Todavía está buscando un múltiplo de 3 que es MENOS DE -10. En este caso, -12. (-10) – (-12) = 2