Почему эта конкретная операция переполняется (ср.CS0220) в C #?
-
23-08-2019 - |
Вопрос
Я пытаюсь создать большой Int64 с информацией о клочках, хранящейся в байтах.
Следующие строки кода работают так, как ожидалось:
Console.WriteLine("{0:X12}", (Int64)(0x0d * 0x100000000));
Console.WriteLine("{0:X12}", (Int64)(0x0d * 0x1000000));
Console.WriteLine("{0:X12}", (Int64)(0x0d * 0x100000));
Почему следующая строка приводит к ошибке компиляции CS0220 "Операция переполняется во время компиляции в режиме checked", а остальные нет?
Console.WriteLine("{0:X12}", (Int64)(0x0d * 0x10000000));
Результатом было бы:
FFFFFFFFD0000000
вместо того , чтобы:
0000D0000000
Кто-нибудь может это объяснить?Теперь я буду конвертировать с помощью операторов сдвига, но все же любопытно, почему этот подход не работает!
Обновить:Ошибка также возникает при использовании (Int64)(0x0d << 28).
Решение
Вам нужно специально пометить значения констант как longs (Int64s) или, возможно, ulongs (UInt64s), в противном случае по умолчанию они будут интерпретироваться как целые числа (т.Е.Int32s), явно вызывающий переполнения.Приведение после операции умножения в этом случае не принесет вам никакой пользы.
Еще не тестировал, но этот код должен работать:
Console.WriteLine("{0:X12}", 0x0dL * 0x100000000L);
Console.WriteLine("{0:X12}", 0x0dL * 0x1000000L);
Console.WriteLine("{0:X12}", 0x0dL * 0x100000L);
Другие советы
Целочисленные литералы имеют тип Int32 (даже если они в шестнадцатеричном формате).Используйте суффикс "L", чтобы сделать их длинными (Int64).
Console.WriteLine("{0:X12}", 0x0dL * 0x100000000L);
На первый взгляд я бы предположил, что он выполняет умножение с помощью Int32 и переполняется.Вам нужно преобразовать отдельные операнды в Int64, а затем умножить их.Прямо сейчас вы только формируете результат.
Тем не менее, я не знаю, почему он обнаружит проблему только с этой одной строкой, а не с первой с большим числом.
НАЙТИ