Я хочу преобразовать longв int.
Если значение long> int.MaxValue, я с радостью позволю ему обернуться.
Как лучше всего?
Ответы:
Просто сделай (int)myLongValue. Он будет делать именно то, что вы хотите (отбрасывая MSB и принимая LSB) в uncheckedконтексте (который является компилятором по умолчанию). Он будет вставлен OverflowExceptionв checkedконтекст, если значение не соответствует int:
int myIntValue = unchecked((int)myLongValue);
new Random()использует Environment.TickCountпод капотом; нет необходимости засеивать вручную по тикам часов.
unchecked, поэтому, если вы явно не изменили его, uncheckedключевое слово (как показано в этом ответе и комментарии @CrisMarisic и т. Д.) Не требуется и int myIntValue = (int)myLongValueполностью эквивалентно. Однако обратите внимание, что независимо от того, используете ли вы uncheckedключевое слово или нет, вы получаете нематематическое грубое усечение, описанное @TJCrowder, когда знак может перевернуться в некоторых случаях переполнения. Единственный способ по-настоящему гарантировать математическую корректность - использовать checked(...)контекст, в котором эти случаи вызовут исключение.
Convert.ToInt32(myValue);
Хотя я не знаю, что он будет делать, если он больше int.MaxValue.
OverflowException, а это именно то, чего OP не хочет: msdn.microsoft.com/en-us/library/d4haekc4.aspx
Convertэто нехорошо.
if (value > Int32.MaxValue) return Int32.MaxValue; else return Convert.ToInt32( value );
Иногда вас действительно интересует не фактическое значение, а его использование в качестве контрольной суммы / хэш-кода . В этом случае GetHashCode()хорошим выбором будет встроенный метод :
int checkSumAsInt32 = checkSumAsIn64.GetHashCode();
GetHashCodeэто подходящий выбор. Если вам нужна постоянная контрольная сумма - значение, которое будет таким же, когда вы запустите приложение позже, то не используйте GetHashCode, поскольку не гарантируется, что это будет один и тот же алгоритм навсегда.
Самый безопасный и быстрый способ - использовать Bit Masking перед кастом ...
int MyInt = (int) ( MyLong & 0xFFFFFFFF )
Значение Bit Mask ( 0xFFFFFFFF) будет зависеть от размера Int, потому что размер Int зависит от машины.
uncheckedконтексте вы не получите переполнения, но вам не нужно маскироваться, uncheckedчтобы избежать переполнения, поэтому решение требуется только в checkedконтексте.] Пример для 16-бит. 16-битные со знаком (-32768, 32767). Маскирование с помощью 0xFFFF допускает значение до 65535, вызывая переполнение IIRC. Может маскировать, чтобы избежать бит знака, 0x7FFF или 0x7FFFFFFF, если нужен только положительный результат.
Возможный способ - использовать оператор по модулю, чтобы значения оставались только в диапазоне int32, а затем преобразовать его в int.
var intValue= (int)(longValue % Int32.MaxValue);
Он может конвертировать
Convert.ToInt32 метод
Но он вызовет исключение OverflowException, если значение выходит за пределы диапазона типа Int32. Базовый тест покажет нам, как это работает:
long[] numbers = { Int64.MinValue, -1, 0, 121, 340, Int64.MaxValue };
int result;
foreach (long number in numbers)
{
try {
result = Convert.ToInt32(number);
Console.WriteLine("Converted the {0} value {1} to the {2} value {3}.",
number.GetType().Name, number,
result.GetType().Name, result);
}
catch (OverflowException) {
Console.WriteLine("The {0} value {1} is outside the range of the Int32 type.",
number.GetType().Name, number);
}
}
// The example displays the following output:
// The Int64 value -9223372036854775808 is outside the range of the Int32 type.
// Converted the Int64 value -1 to the Int32 value -1.
// Converted the Int64 value 0 to the Int32 value 0.
// Converted the Int64 value 121 to the Int32 value 121.
// Converted the Int64 value 340 to the Int32 value 340.
// The Int64 value 9223372036854775807 is outside the range of the Int32 type.
Здесь есть более подробное объяснение.
Не стал бы
(int) Math.Min(Int32.MaxValue, longValue)
быть правильным, математически говоря?
longValue до ближайшего представимого , intесли исходное значение является огромным. Но ему не хватает такой же обработки слишком отрицательных входных данных, которые вместо этого потеряли бы наиболее значимые биты; вам также нужно будет сравнить Int32.MinValue. Однако исходный плакат, похоже, не нуждался в зажимах.
myIntValueможет оказаться отрицательным, когдаmyLongValueположительно (4294967294 => -2), и наоборот (-4294967296 => 0). ТакCompareTo, например, при реализации операции вы не можете успешноlongпреобразовать результат вычитания одного из другогоintи вернуть его; для некоторых значений сравнение даст неверный результат.