Respostas:
Apenas faça (int)myLongValue
. Ele fará exatamente o que você deseja (descartando MSBs e recebendo LSBs) no unchecked
contexto (que é o padrão do compilador). Será lançada OverflowException
no checked
contexto se o valor não couber em um int
:
int myIntValue = unchecked((int)myLongValue);
new Random()
usa Environment.TickCount
sob o capô; não é necessário semear manualmente com marcações de relógio.
unchecked
, portanto, a menos que você o tenha alterado explicitamente, a unchecked
palavra - chave (conforme mostrado nesta resposta e no comentário de @ ChrisMarisic etc.) não é necessária e int myIntValue = (int)myLongValue
é exatamente equivalente. No entanto, observe que, independentemente de você usar unchecked
ou não a palavra - chave, você está obtendo o comportamento de truncamento não-matemático descrito por @TJCrowder, em que o sinal pode virar em alguns casos de estouro. A única maneira de garantir verdadeiramente a correção matemática é usar o checked(...)
contexto, onde esses casos gerarão uma exceção.
Convert.ToInt32(myValue);
Embora eu não saiba o que fará quando for maior que int.MaxValue.
OverflowException
, exatamente o que o OP não deseja: msdn.microsoft.com/en-us/library/d4haekc4.aspx
Convert
não é bom.
if (value > Int32.MaxValue)
return Int32.MaxValue;
else
return Convert.ToInt32( value );
Às vezes, você não está realmente interessado no valor real, mas em seu uso como soma de verificação / código de hash . Nesse caso, o método interno GetHashCode()
é uma boa opção:
int checkSumAsInt32 = checkSumAsIn64.GetHashCode();
GetHashCode
será uma escolha apropriada. Se você estiver buscando uma soma de verificação persistente - um valor que será o mesmo quando você executar o aplicativo posteriormente, não use GetHashCode
, pois não é garantido que ele seja o mesmo algoritmo para sempre.
A maneira mais rápida e segura é usar o Bit Masking antes do lançamento ...
int MyInt = (int) ( MyLong & 0xFFFFFFFF )
O 0xFFFFFFFF
valor da máscara de bits ( ) dependerá do tamanho de Int porque o tamanho de Int depende da máquina.
unchecked
contexto você não receberá um estouro - mas não precisará mascarar-se unchecked
para evitar o estouro; portanto, uma solução é necessária apenas no checked
contexto.] Exemplo para 16 bits. Retenções assinadas de 16 bits (-32768, 32767). O mascaramento com 0xFFFF permite valores de até 65535, causando estouro, IIRC. Pode mascarar para evitar o bit de sinal, 0x7FFF ou 0x7FFFFFFF, se desejar apenas positivo.
Pode converter por
Método Convert.ToInt32
Mas ele lançará uma OverflowException se o valor estiver fora do intervalo do Tipo Int32. Um teste básico nos mostrará como funciona:
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.
Aqui há uma explicação mais longa.
Não
(int) Math.Min(Int32.MaxValue, longValue)
ser o caminho correto, matematicamente falando?
longValue
ao representável mais próximo int
se o valor original é enorme. Mas falta o mesmo tratamento para entradas muito negativas, que perderiam os bits mais significativos; você precisaria comparar com Int32.MinValue
também. O pôster original não parecia querer fixação, no entanto.
myIntValue
pode acabar negativo quandomyLongValue
positivo (4294967294 => -2
) e vice-versa (-4294967296 => 0
). Portanto, ao implementar umaCompareTo
operação, por exemplo, você não pode converter felizmente o resultado de subtrair umlong
do outro para umint
e retornar esse valor; para alguns valores, sua comparação produziria um resultado incorreto.