2015-03-26 17 views
6

Dato questo esempio:Modulo operatore (%) dà risultati divergenti

std::vector<int> numbers = {5,6,7}; //size is 3 
int i = -1; 
std::cout << i % 3 <<"\n";     // output: -1 
std::cout << i % numbers.size() << "\n"; // output: 0 

sostanzialmente in entrambe le istruzioni im elaborazione -1% 3, ma le uscite compilatore numeri differenti. Non capisco questo risultato, forse qualcuno può spiegarmelo.

edit: come @ Chris, @ Keith Thompson @AnT suggerito il frammento di

std::cout << std::numeric_limits<std::size_t>::max() % 3 <<"\n";  //output: 0 
std::cout << i % numbers.size() << "\n";       // output: 0 

stampe i risultati attesi. Grazie per l'utile consiglio a tutti!

+0

Vedere qui: http://stackoverflow.com/questions/7594508/modulo-operator-with-negative-values ​​ –

+2

@ RollenD'Souza: Questo è in realtà non correlato. – Deduplicator

+2

Il problema è che "numbers.size()" sembra essere "unsigned int"; e il "-1" viene convertito in "0xffffffff" (o qualunque sia il valore per la tua architettura) dietro la schiena :( – FoggyDay

risposta

8

i % 3 è ciò che ci si aspetta e, poiché C++ 11, ha definito la semantica piuttosto che avere un risultato definito dall'implementazione (se ricordo correttamente).

numbers.size() ha un tipo senza segno (std::size_t). Supponendo che size_t sia grande come int o superiore, i viene convertito nello stesso tipo senza segno prima che l'operazione venga eseguita. Il valore i ottiene sarà il valore massimo per quel tipo, che sembra essere divisibile per 3 per te.

+3

Come nota a margine, l'attivazione del livello di avviso sul compilatore dovrebbe aver rilevato la mancata corrispondenza del segno – Deduplicator

+0

@Deduplicator, interessante, non lo sapevo. Apparentemente [Clang non lo è] (http://coliru.stacked-crooked.com/a/e425e23f148a1f03), [né GCC] (http: // coliru. stacked-crooked.com/a/7353cc43b82d22c3), o almeno queste versioni: – chris

+0

Prova '-Weverything', e guarda quale avviso hanno buttato fuori da' -Wextra'. – Deduplicator

0

Il problema è% di numeri negativi non è ben definito in C++.

+0

Tranne da C++ 11 in poi. – EJP

Problemi correlati