Подтвердить что ты не робот

Есть ли разница между назначением литых и сильных типов?

Я как-то наткнулся на это сегодня, когда писал код. В качестве примера возьмем следующее:

long valueCast  = (long)(10 + intVariable);
long valueTyped = 10L + intVariable;

Есть ли разница между этими двумя или они скомпилированы точно так же? Есть ли соглашение для одного над другим?

Итак, я знаю, что это не критический вопрос (оба работают). Мне просто очень интересно узнать, какие отличия могут быть!

EDIT. Изменен пример кода, который будет ближе к моему первоначальному сценарию. Я хотел, чтобы вопрос был ясен, поэтому я заменил переменную константой. Не понял, что компилятор автоматически выполнил арифметику (тем самым изменив ответы на этот вопрос)

4b9b3361

Ответ 1

Да, между этими двумя есть большая разница. Не для тех конкретных значений, но то же самое выражение с разными значениями покажет разницу.

В первой версии добавление выполняется в 32-разрядной арифметике, а затем результат преобразуется в long.

Во второй версии первый операнд уже есть long, поэтому второй операнд продвигается до long, и добавление затем выполняется в 64-разрядной арифметике.

Конечно, в этом случае компилятор все равно будет выполнять арифметику (и в обоих случаях прийти к одному и тому же выводу), но важно понять разницу между преобразованием результата операции и преобразованием одного из операндов операция.

В качестве примера:

unchecked
{
    long valueCast  = (long)(2000000000 + 2000000000);
    long valueTyped = 2000000000L + 2000000000;
    Console.WriteLine(valueCast);
    Console.WriteLine(valueTyped);
}

Результат:

-294967296
4000000000

Обратите внимание, что это нужно делать в явно неконтролируемом контексте, поскольку в противном случае первое добавление даже не будет компилироваться - вы получите сообщение об ошибке "CS0220: операция переполняется во время компиляции в режиме проверки".

Ответ 2

Ну, это ошибка компиляции:

long valueCast = (long)(2147483647 + 2);

"Операция переполняется во время компиляции в режиме проверки."

В то время как это прекрасно работает:

long valueTyped = (2147483647L + 2);

Как говорит Джон Скит, разница заключается в том, конвертируете ли вы в long перед выполнением суммы или после нее.

Ответ 3

В вашем примере 10L + 2; равен ((длинный) 10) + 2;

Это не то же самое (длинное) (10 + 2), потому что:

Операция

(long) (10 + 2) выполняется как int (32 бит), а затем преобразуется в длинный (64-битный)

((длинный) 10) + 2; операция выполняется так долго (64 бит), потому что 10 преобразуется в задолго до фактической операции