Проблема в том, что литерал "99" трактуется как int. Если вы добавите «L», это будет рассматриваться как длинный. Чтобы исправить проблему с компиляцией:
long test2 = 99L * 99L * 99L * 99L * 99L;
И исправить «неправильный результат», вызванный переполнением целого числа:
long r = 99;
long test1 = r * r * r * r * r;
Ключевым моментом является то, что выражение справа от "=" вычисляется до присвоения long r
.
Существуют и другие буквальные суффиксы, которые могут вас заинтересовать:
Type Suffix Example
uint U or u 100U
long L or l 100L
ulong UL or ul 100UL
float F or f 123.45F
decimal M or m 123.45M
@m.edmonson, касательно вашего вопроса о том, почему он приходит к 919965907. Что происходит, так это то, что значение «оборачивается» вокруг int.MaxValue. Вы можете увидеть это с помощью небольшой тестовой программы:
int i = 99; // 99
i *= 99; // 9801
i *= 99; // 970299
i *= 99; // 96059601
i *= 99; // 919965907 should be 9509900499 but comes out to 919965907
// which is (9509900499 % int.MaxValue)
long k = 9509900499 % int.MaxValue;
Что подразумевается под "обёртыванием"? Когда вы превышаете int.MaxValue
на 1, значение «возвращается» к int.MinValue
.
int j = int.MaxValue;
j++;
bool isNowMinValue = (j == int.MinValue); // true, the value has "wrapped around"
Это немного упрощенно; если вы будете искать «переполнение целых чисел», вы получите лучшее объяснение. Стоит понять, как целые числа (и другие числовые типы) представлены 32-битными:
http://en.wikipedia.org/wiki/Signed_number_representations