¿ANSI C o ISO C especifica qué debería ser -5% 10?

Me parece recordar que ANSI C no especificó qué valor se debe devolver cuando cualquier operando de un operador de módulo es negativo (solo que debe ser consistente). ¿Se especificó más tarde o siempre se especificó y recuerdo incorrectamente?

C89, no totalmente (§3.3.5 / 6). Puede ser -5 o 5, porque -5 / 10 puede devolver 0 o -1 ( % se define en términos de una ecuación lineal que involucra / , * y + ):

Cuando los enteros se dividen y la división es inexacta, si ambos operandos son positivos, el resultado del operador / es el entero más grande menor que el cociente algebraico y el resultado del operador % es positivo. Si cualquiera de los operandos es negativo , si el resultado del operador / es el entero más grande menor que el cociente algebraico o el entero más pequeño mayor que el cociente algebraico está definido por la implementación , como es el signo del resultado del operador % . Si el cociente a/b es representable, la expresión (a/b)*b + a%b será igual a .

C99, sí (§6.5.5 / 6), el resultado debe ser -5:

Cuando los enteros se dividen, el resultado del operador / es el cociente algebraico con cualquier parte fraccional descartada. 88) Si el cociente a/b es representable, la expresión (a/b)*b + a%b será igual a .

88) Esto a menudo se llama “truncamiento hacia cero”.


Del mismo modo, en C ++ 98 el resultado es la implementación definida (§5.6 / 4), siguiendo la definición de C89, pero menciona que se prefiere la regla de redondear a cero,

… Si ambos operandos son no negativos, el rest no es negativo; si no, el signo del rest está definido por la implementación 74) .

74) Según el trabajo en curso para la revisión de ISO C, el algoritmo preferido para la división de enteros sigue las reglas definidas en el estándar ISO Fortran, ISO / IEC 1539: 1991, en el que el cociente siempre se redondea hacia cero.

y de hecho se convierte en la regla estándar en C ++ 0x (§5.6 / 4):

… Para operandos integrales, el operador / produce el cociente algebraico con cualquier parte fraccional descartada; 82

82) Esto a menudo se llama truncamiento hacia cero.

Para agregar un pequeño detalle a la respuesta de KennyTM: Si los Estándares C llaman a algo definido, entonces se requiere esa implementación para documentar la elección que hace. Por lo general, esto estaría en la documentación del comstackdor o de la biblioteca (página del manual, manual de ayuda, documentos impresos, folleto del CD :-). Cualquier implementación que alegue conformidad con C89 o posterior debe proporcionar esto en alguna parte. Intente buscar tal documento. En el caso de gcc por ejemplo, esto está en la información de gcc:

4 C Comportamiento definido por la implementación


Se requiere una implementación conforme de ISO C para documentar su elección de comportamiento en cada una de las áreas designadas como “implementación definida”. A continuación se enumeran todas estas áreas, junto con los números de sección de las normas ISO / IEC 9899: 1990 e ISO / IEC 9899: 1999. Algunas áreas solo están definidas por la implementación en una versión del estándar.

Algunas opciones dependen del ABI determinado externamente para la plataforma (incluidas las codificaciones de caracteres estándar) que sigue GCC; estos se enumeran como “determinados por ABI” a continuación. * Nota Compatibilidad Binaria: Compatibilidad, y `http://gcc.gnu.org/readings.html ‘. Algunas opciones están documentadas en el manual del preprocesador. * Nota Comportamiento definido por la implementación: (cpp) Comportamiento definido por la implementación. La biblioteca y el sistema operativo (u otro entorno cuando se comstackn para un entorno independiente) seleccionan algunas opciones; consulte su documentación para más detalles.

  • Menú:

  • Implementación de traducción ::

  • Implementación del entorno ::
  • Implementación de identificadores ::
  • Implementación de personajes ::
  • Implementación de enteros ::
  • Implementación de punto flotante ::
  • Implementación de matrices y punteros ::
  • Implementación de sugerencias ::
  • Enumeraciones de uniones de estructuras y implementación de bit-fields ::
  • Implementación de calificadores ::
  • Implementación de los declaradores ::
  • Implementación de declaraciones ::
  • Implementación de directivas de preprocesamiento ::
  • Implementación de funciones de biblioteca ::
  • Implementación de architecture ::
  • Implementación de comportamiento específico de la configuración regional ::