ANSI C o ISO C specifica cosa dovrebbe essere -5% 10?

Mi sembra di ricordare che ANSI C non ha specificato quale valore deve essere restituito quando uno degli operandi di un operatore modulo è negativo (solo che dovrebbe essere coerente). È stato specificato in seguito, o è sempre stato specificato e sto ricordando in modo errato?

C89, non totalmente (§3.3.5 / 6). Può essere -5 o 5, perché -5 / 10 può restituire 0 o -1 ( % è definito in termini di un’equazione lineare che coinvolge / , * e + ):

Quando gli interi sono divisi e la divisione è inesatta, se entrambi gli operandi sono positivi, il risultato dell’operatore / è il più grande intero meno del quoziente algebrico e il risultato dell’operatore % è positivo. Se uno degli operandi è negativo , se il risultato dell’operatore / è il più grande intero meno del quoziente algebrico o il più piccolo intero maggiore del quoziente algebrico è definito dall’implementazione , come il segno del risultato dell’operatore % . Se il quoziente a/b è rappresentabile, l’espressione (a/b)*b + a%b deve essere uguale a .

C99, sì (§6.5.5 / 6), il risultato deve essere -5:

Quando gli interi sono divisi, il risultato dell’operatore / è il quoziente algebrico con qualsiasi parte frazionaria scartata. 88) Se il quoziente a/b è rappresentabile, l’espressione (a/b)*b + a%b deve essere uguale a .

88) Questo è spesso chiamato “troncatura verso zero”.


Allo stesso modo, in C ++ 98 il risultato è definito dall’implementazione (§5.6 / 4), seguendo la definizione del C89, ma menziona che la regola round-zero è preferita,

… Se entrambi gli operandi non sono negativi, il resto non è negativo; in caso contrario, il segno del resto è definito dall’implementazione 74) .

74) Secondo i lavori in corso verso la revisione di ISO C, l’algoritmo preferito per la divisione integer segue le regole definite nello standard ISO Fortran, ISO / IEC 1539: 1991, in cui il quoziente è sempre arrotondato a zero.

e infatti diventa la regola standard in C ++ 0x (§5.6 / 4):

… Per gli operandi integrali l’operatore / restituisce il quoziente algebrico con qualsiasi parte frazionaria scartata; 82

82) Questo è spesso chiamato troncamento verso zero.

Per aggiungere un piccolo dettaglio alla risposta di KennyTM: Se gli standard C chiamano un’implementazione definita, allora quell’implementazione è necessaria per documentare la scelta che fa. Di solito questo sarebbe nel compilatore o nella documentazione della biblioteca (pagina man, manuale di aiuto, documenti stampati, libretto del CD 🙂 Qualsiasi implementazione che rivendichi la conformità a C89 o successiva deve fornire questo da qualche parte. Prova a cercare un documento del genere. Ad esempio, nel caso di gcc , questo è nel gcc-info:

4 C Comportamento definito dall’implementazione


È necessaria un’implementazione conforms di ISO C per documentare la sua scelta di comportamento in ciascuna delle aree definite “implementate”. Di seguito sono elencate tutte queste aree, insieme ai numeri di sezione degli standard ISO / IEC 9899: 1990 e ISO / IEC 9899: 1999. Alcune aree sono solo definite dall’implementazione in una versione dello standard.

Alcune scelte dipendono dall’ABI determinato esternamente per la piattaforma (incluse le codifiche di caratteri standard) seguite da GCC; questi sono elencati come “determinati da ABI” di seguito. * Nota compatibilità binaria: compatibilità e `http://gcc.gnu.org/readings.html ‘. Alcune scelte sono documentate nel manuale del preprocessore. * Nota Comportamento definito dall’implementazione: (cpp) Comportamento definito dall’implementazione. Alcune scelte sono fatte dalla libreria e dal sistema operativo (o da un altro ambiente durante la compilazione per un ambiente indipendente); fare riferimento alla loro documentazione per i dettagli.

  • Menu:

  • Implementazione della traduzione ::

  • Implementazione dell’ambiente ::
  • Implementazione degli identificatori ::
  • Implementazione di personaggi ::
  • Implementazione di interi ::
  • Implementazione in virgola mobile ::
  • Implementazione di matrici e puntatori ::
  • Implementazione di suggerimenti ::
  • Enumerazioni delle unioni delle strutture e implementazione dei campi di bit ::
  • Implementazione dei qualificatori ::
  • Implementazione di dichiaratori ::
  • Implementazione delle dichiarazioni ::
  • Implementazione delle direttive di pre-elaborazione ::
  • Implementazione delle funzioni di libreria ::
  • Implementazione dell’architettura ::
  • Implementazione del comportamento specifico della locale ::