Matemáticas:¿Por qué C++ genera números negativos cuando usa módulo?
Si usted tiene una ecuación como esta:
x = 3 mod 7
x podrían ser ... -4, 3, 10, 17, ..., o más en general:
x = 3 + k * 7
donde k puede ser cualquier número entero. No sé de una operación de módulo definida para matemáticas, pero el anillo de factores sí lo es.
Python:
En Python, siempre obtendrá valores no negativos cuando se utiliza %
con un resultado positivo m
:
#!/usr/bin/python
# -*- coding: utf-8 -*-
m = 7
for i in xrange(-8, 10 + 1):
print(i % 7)
Resultados en:
6 0 1 2 3 4 5 6 0 1 2 3 4 5 6 0 1 2 3
C++:
salida#include <iostream>
using namespace std;
int main(){
int m = 7;
for(int i=-8; i <= 10; i++) {
cout << (i % m) << endl;
}
return 0;
}
Will:
-1 0 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 0 1 2 3
ISO/IEC 14882: 2003 (E) - 5,6 operadores multiplicativos:
The binary/operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of/or % is zero the behavior is undefined; otherwise (a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined 74).
y
74) According to work underway toward the revision of ISO C, the preferred algorithm for integer division follows the rules defined in the ISO Fortran standard, ISO/IEC 1539:1991, in which the quotient is always rounded toward zero.
Fuente: ISO/IEC 14882:2003(E)
(No pude encontrar una versión gratuita de ISO/IEC 1539:1991
. ¿Alguien sabe dónde conseguirlo desde)
La operación parece definirse así:?
Pregunta:
¿Tiene sentido para definir así?
¿Cuáles son los argumentos para esta especificación? ¿Hay algún lugar donde las personas que crean dichos estándares lo discutan? ¿Dónde puedo leer algo sobre las razones por las que decidieron hacerlo de esta manera?
La mayoría de las veces, cuando uso módulo, quiero acceder a los elementos de una estructura de datos. En este caso, tengo que asegurarme de que el mod devuelva un valor no negativo. Entonces, para este caso, sería bueno que el mod siempre devuelva un valor no negativo. (Otro uso es el Euclidean algorithm. Como podría hacer que ambos números sean positivos antes de usar este algoritmo, el signo del módulo sería importante.)
El material adicional:
Ver Wikipedia para una larga lista de lo que hace de módulo en diferentes idiomas.
La razón habitual para C (y por lo tanto C++) es que el hardware existente hace las matemáticas de cierta manera. El estándar de idioma solo documenta lo que está sucediendo (y lo que no). –
Una adición útil a esta pregunta podría ser "¿y cuál es una buena alternativa en el código C++ para obtener el comportamiento mostrado por Python?" – hertzsprung