2008-11-26 4 views
29

Supponiamo che a e siano entrambi di tipo int e sia diverso da zero. Prendere in considerazione il risultato di eseguire a/b nei seguenti casi:Arrotondamento divisione intera con negativi in ​​C++

  1. a e b sono entrambi non negativo.
  2. a e b sono entrambi negativi.
  3. Esattamente uno di questi è negativo.

Nel caso 1, il risultato viene arrotondato per difetto all'intero più vicino. Ma cosa dice lo standard sui casi 2 e 3? Una vecchia bozza che ho trovato su Internet indica che dipende dall'implementazione (sì, anche il caso 2), ma il comitato si sta orientando verso il fatto di renderlo sempre "tondo verso zero". Qualcuno sa cosa dice lo standard (più recente)? Si prega di rispondere solo in base allo standard, non è ciò che ha senso, o cosa fanno particolari compilatori.

+1

Incredibile opportunità di ricerca data la natura di 1200 pagine dello standard. Ho intenzione di dargli una rapida grep e rinunciare :) –

risposta

22

Secondo la revisione maggio 2008

Hai ragione:

Il/operatore binario produce il quoziente, e l'operatore binario% restituisce il resto della divisione della prima espressione da il secondo. Se il secondo operando di/o% è zero, il comportamento non è definito; altrimenti (a/b) * b + a% b è uguale a a. Se entrambi gli operandi non sono negativi, il resto non è negativo; in caso contrario, il segno del resto è definito dall'implementazione75).

Nota 75 dice:

Secondo lavori in corso verso la revisione della norma ISO C, l'algoritmo preferito per la divisione intera segue le regole definite nello standard ISO Fortran, ISO/IEC 1539: 1991, in cui il quoziente è sempre arrotondato verso zero.

Le probabilità sono che C++ tarderà C in questo senso. Così com'è, è indefinito ma hanno un occhio verso il cambiamento.

Lavoro nello stesso dipartimento di Stroustrup e con un membro del comitato. Le cose prendono ETÀ per essere compiute, e sono infinitamente politiche. Se sembra sciocco, probabilmente lo è.

+7

L'affermazione citata è vecchia. Risale allo standard C++ 98 e si riferisce alla revisione C99. C99 specifica l'arrotondamento verso zero e C++ 11 segue l'esempio. – Jed

7

Solo un commento. L'attuale bozza di lavoro per lo standard C++ corregge infatti il ​​problema "definito dall'implementazione" e chiede il troncamento verso zero. Here è la pagina Web del comitato e here è la bozza. Il problema è a pagina 112.

17

come aggiornamento alle altre risposte:

L'ultima bozza del C++ 11, n3242 che è per gli scopi più pratici identica a quella attuale standard di C++ 11, dice questo in 5.6 punto 4 (pagina 118):

Per gli operandi integrali la/operatore produce il quoziente algebrica con qualsiasi parte frazionaria scartato; (Vedi nota 80)

Nota 80 stati (si noti che le note sono non-normativo):

80) Questo è spesso chiamato il troncamento verso lo zero.

Point 4 prosegue affermando:

se il quoziente a/b è rappresentabile nel tipo di risultato, (a/b) * b + a% b è uguale a un .

che può essere mostrato a richiedere il segnale di a%b essere lo stesso come il segno di a (quando non zero).

-1

A volte abbiamo bisogno di fare un passo indietro, e guardare solo la matematica di essa:

Dato int x, int y

se int i1 = x/y e int i2 = x% y

allora y * i1 + i2 deve essere x

quindi non si tratta tanto di standard, ma c'è solo un modo in cui questo può eventualmente essere. Se qualsiasi standard gli consente di essere in un altro modo, allora lo standard è sbagliato, e ciò significa che la lingua è rotta.