Я хочу преобразовать long
в int
.
Если значение long
> int.MaxValue
, я с радостью позволю ему обернуться.
Как лучше всего?
c#
types
int
type-conversion
long-integer
несмотря
источник
источник
myIntValue
может оказаться отрицательным, когдаmyLongValue
положительно (4294967294 => -2
), и наоборот (-4294967296 => 0
). ТакCompareTo
, например, при реализации операции вы не можете успешноlong
преобразовать результат вычитания одного из другогоint
и вернуть его; для некоторых значений сравнение даст неверный результат.new Random()
используетEnvironment.TickCount
под капотом; нет необходимости засеивать вручную по тикам часов.unchecked
, поэтому, если вы явно не изменили его,unchecked
ключевое слово (как показано в этом ответе и комментарии @CrisMarisic и т. Д.) Не требуется иint myIntValue = (int)myLongValue
полностью эквивалентно. Однако обратите внимание, что независимо от того, используете ли выunchecked
ключевое слово или нет, вы получаете нематематическое грубое усечение, описанное @TJCrowder, когда знак может перевернуться в некоторых случаях переполнения. Единственный способ по-настоящему гарантировать математическую корректность - использоватьchecked(...)
контекст, в котором эти случаи вызовут исключение.Хотя я не знаю, что он будет делать, если он больше int.MaxValue.
источник
OverflowException
, а это именно то, чего OP не хочет: msdn.microsoft.com/en-us/library/d4haekc4.aspxConvert
это нехорошо.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);
источник
Следующее решение будет усечено до int.MinValue / int.MaxValue, если значение выходит за границы Integer.
myLong < int.MinValue ? int.MinValue : (myLong > int.MaxValue ? int.MaxValue : (int)myLong)
источник
Он может конвертировать
Но он вызовет исключение 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
. Однако исходный плакат, похоже, не нуждался в зажимах.