Я хочу , щоб перетворити long
в int
.
Якщо значення long
> int.MaxValue
, я радий дозволити йому обернутися.
Який найкращий спосіб?
Я хочу , щоб перетворити long
в int
.
Якщо значення long
> int.MaxValue
, я радий дозволити йому обернутися.
Який найкращий спосіб?
Відповіді:
Просто роби (int)myLongValue
. Він зробить саме те, що ви хочете (відмови від MSB та прийняття LSB) у unchecked
контексті (що є типовим для компілятора). Він буде кинутий OverflowException
у checked
контекст, якщо значення не вписується у int
:
int myIntValue = unchecked((int)myLongValue);
new Random()
використовує Environment.TickCount
під кришкою; не потрібно сіяти вручну за допомогою годинникових кліщів.
unchecked
, тому якщо ви явно не змінили його, unchecked
ключове слово (як показано у цій відповіді та коментарі @ ChrisMarisic тощо) не потрібне і int myIntValue = (int)myLongValue
є рівнозначним. Однак зауважте, що незалежно від того, використовуєте ви unchecked
ключове слово чи ні, ви отримуєте нематематичну грубу поведінку усічення, описану @TJCrowder, де знак може перевертатись у деяких випадках переповнення. Єдиний спосіб по-справжньому забезпечити математичну правильність - це використовувати checked(...)
контекст, де ці випадки будуть винятком.
Convert.ToInt32(myValue);
Хоча я не знаю, що це зробить, коли це більше, ніж int.MaxValue.
OverflowException
, що саме ОП не хоче: 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
, оскільки не гарантується, що він буде завжди тим самим алгоритмом.
Найбезпечнішим і швидким способом є використання біт-маскування перед викликом ...
int MyInt = (int) ( MyLong & 0xFFFFFFFF )
Значення Bit Mask ( 0xFFFFFFFF
) буде залежати від розміру Int, оскільки розмір Int залежить від машини.
unchecked
контексті ви не отримаєте переповнення, але вам не потрібно маскуватися, unchecked
щоб уникнути переповнення, тому рішення потрібно лише в checked
контексті.] Приклад для 16-біт. Підписано 16-бітові затримки (-32768, 32767). Маскування за допомогою 0xFFFF дозволяє отримати значення до 65535, викликаючи переповнення, IIRC. Не вдалося замаскувати, щоб уникнути бітових знаків, 0x7FFF або 0x7FFFFFFF, якщо потрібно лише позитив.
Він може конвертувати
Метод 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
і повертати це; для деяких значень ваше порівняння дасть неправильний результат.