2014-09-18 8 views
12

pracuje na przypisanie do klasy, wpadłem na ten (zauważ warunkowego pętli)C++ wydaje się naruszać właściwości oprócz

// This one works. 
for (int k = 0; k + negwords[j].length() < comments[i].length(); k++) { 
    if (comments[i].substr(k, negwords[j].length()) == negwords[j]) { 
     negativeScore++; 
    } 
} 
//*/ 

/*/ This one doesn't: It fails with an out-of-bounds index. 
for (int k = 0; k < comments[i].length() - negwords[j].length(); k++) { 
    if (comments[i].substr(k, negwords[j].length()) == negwords[j]) { 
     negativeScore++; 
    } 
} 
//*/ 

Dlaczego jest tak, że pierwszy z nich działa, ale drugi nie robi” t? Czy chodzi o kolejność operacji, bool force na int, łączność operatorów, czy OBOE?

+10

Czy 'length()' zwraca niepodpisany typ? –

+1

nie powinien być k + komentarzem [i] .length() cyan

+0

@cyan: Nie, jeśli odejmiesz 'negwords [i] .length()' od obu stron warunku pierwszej pętli, otrzymasz drugi. –

Odpowiedz

33

Jeśli jeden negwords[j].length() lub comments[i].length() zwracają nieoznaczoną integralną typ co najmniej tak duży jak unsigned int, następnie k będą promowane do tego samego typu unsigned i zasady będą miały zastosowanie oprócz modułowego.

Jako przykład oznacza to, że 1 < 2 - 3 jest prawdziwe, ponieważ 2 - 3 owija się w arytmetykę modułową, stając się bardzo dużą liczbą.

Jeśli jesteś zainteresowany, to zachowanie jest określone w sekcji 3.9.1 niniejszego standardu, który obejmuje zasadę:

liczb całkowitych bez znaku powinien stosować się do prawa arytmetyki modulo 2 n gdzie n to liczba bitów w reprezentacji wartości tego konkretnego rozmiaru liczby całkowitej.

I przypis dotyczące wpływu:

Oznacza to, że bez znaku arytmetyczna nie przeleje ponieważ wynik, który nie może być reprezentowane przez otrzymanej unsigned całkowitej redukuje modulo dla numeru jedna większa od największej wartości, która może być reprezentowana przez wynikowy typ liczby całkowitej bez znaku.


Matematycy wiedzieć tego typu arytmetyczną algebry pól Galois . W C++ jest on używany do niepodpisanych typów integralnych. Inne typy nie używają arytmetyki modułowej, ale nie używają też zwykłej arytmetyki klasy szkolnej (formalnie, algebry liczb rzeczywistych), ponieważ normalna arytmetyczna wymaga gęstego nieprzeliczalnego zestawu liczb, a komputera skończonego rozmiar nie może reprezentować członków nieskończonego zbioru.

Podziękowania dla Olivera za wskazanie mojego błędu. GF (2)^n reguluje operacje bitowe i wiele innych typowych obliczeń wykonywanych w oprogramowaniu komputerowym, takim jak CRC. Ale nie opisuje on niepodpisanej arytmetyki o wartości większej niż 1 bit, ponieważ wielomiany na polach Galois nie "przenoszą się".

+4

@Cyber: Nie, niedomiar ma wartość "DBL_MIN/2.0 * 2.0" równą zero. To jest zawijanie. –

+0

Ups, mój błąd. – CoryKramer

Powiązane problemy