2013-03-26 4 views
6

Я озадачен на этом фрагменте кода:Почему в этом умножении происходит целочисленное переполнение?

#include <climits> 
#include <iostream> 
int main(void) { 
    using namespace std; 
    cout << "long max " << LONG_MAX << endl; 
    long x = 2 * 1024 * 1024 * 1024; 
    cout << "2 * 1024 * 1024 * 1024 = " << x << endl; 
    return 0; 
} 

Я ожидал , как это должно быть, а я получаю. Использование unsigned не помогает. что дает?

long max 9223372036854775807 
2 * 1024 * 1024 * 1024 = -2147483648 
+0

, если вы наберете '1024', он уже имеет тип данных, причем этот язык является целым числом. Вот почему вам нужно указать '1024L', если вам нужен длинный тип данных. – eis

ответ

11

Добавить L s *. long x = 2L * 1024L * 1024L * 1024L;

(Технически, до тех пор, как один литерал типа long остальные будут продвинуты на long)

Переполнение происходит потому, что 2 и т.д. имеет типа int по умолчанию и переполнение происходит до того назначение.

См. integer literals, который объясняет разные литералы.

+1

И подписанный int имеет максимум '(2^31) - 1', поэтому' 2^31' переполняет это на единицу. (чтобы сделать его более полным). – scones

+0

Я ошибочно подумал, что upcast позаботится об этом, по-видимому, нет. thx – Oliver

+0

@Oliver: переполнение происходит до назначения. Кроме того, обратите внимание, что целочисленное переполнение со знаком является неопределенным поведением на C++. –

Смежные вопросы