Como converter um decimal para um int?
Como converter um decimal para um int?
Respostas:
Use a Convert.ToInt32
partir mscorlib
de
decimal value = 3.14m;
int n = Convert.ToInt32(value);
Veja MSDN . Você também pode usar Decimal.ToInt32
. Mais uma vez, consulte MSDN . Finalmente, você pode fazer um elenco direto como em
decimal value = 3.14m;
int n = (int) value;
que usa o operador de conversão explícito. Veja MSDN .
null
vs. 0
vs. ""
). Eu recomendo não usar Convert a menos que você realmente precisa sua flexibilidade (ou seja, em cenários de tipagem dinâmica)
OverflowException
. Acredito que @Will fornece uma resposta melhor aqui stackoverflow.com/a/501165/39532
Convert.ToInt32
e Decimal.ToInt32
se comportam de forma diferente. Do MSDN: Decimal.ToInt32
- O valor de retorno é a parte integrante do valor decimal; dígitos fracionários são truncados . Convert.ToInt32
- Valor de retorno arredondado para o número inteiro assinado de 32 bits mais próximo. Se o valor estiver na metade do caminho entre dois números inteiros, o número par será retornado; isto é, 4,5 é convertido em 4 e 5.5 é convertido para 6.
Você não pode.
Bem, é claro que você poderia , no entanto, um int (System.Int32) não é grande o suficiente para armazenar todos os valores decimais possíveis.
Isso significa que, se você converter um decimal maior que int.MaxValue, você excederá o limite e se o decimal for menor que int.MinValue, ele ficará insuficiente.
O que acontece quando você está sobrecarregado? Uma de duas coisas. Se sua construção estiver desmarcada (ou seja, o CLR não se importa se você o fizer), seu aplicativo continuará após o valor exceder / exceder o fluxo, mas o valor no int não será o que você esperava. Isso pode levar a erros intermitentes e pode ser difícil de corrigir. Você terminará seu aplicativo em um estado desconhecido, o que pode resultar em seu aplicativo corrompendo quaisquer dados importantes em que ele esteja trabalhando. Não é bom.
Se sua montagem estiver marcada (propriedades-> compilar-> avançado-> verificar se há aritmética de estouro / estouro ou opção de compilador / marcada), seu código lançará uma exceção quando ocorrer um estouro / estouro. Provavelmente é melhor do que não; no entanto, o padrão para montagens não é verificar se há excesso / vazão.
A verdadeira questão é "o que você está tentando fazer?" Sem conhecer seus requisitos, ninguém pode lhe dizer o que você deve fazer neste caso, além do óbvio: NÃO O FAÇA.
Se você NÃO se importa especificamente, as respostas aqui são válidas. No entanto, você deve comunicar seu entendimento de que um estouro pode ocorrer e que isso não importa, envolvendo seu código de conversão em um bloco não verificado
unchecked
{
// do your conversions that may underflow/overflow here
}
Dessa forma, as pessoas que estão atrás de você entendem que você não se importa e, no futuro, alguém alterar suas compilações para / verificadas, seu código não será interrompido inesperadamente.
Se tudo o que você deseja fazer é soltar a parte fracionária do número, deixando a parte integral, você pode usar Math.Truncate.
decimal actual = 10.5M;
decimal expected = 10M;
Assert.AreEqual(expected, Math.Truncate(actual));
int i = (int)d;
lhe dará o número arredondado para baixo.
Se você quiser arredondar para o número par mais próximo (por exemplo,> 0,5 arredondará para cima), poderá usar
int i = (int)Math.Round(d, MidpointRounding.ToEven);
Em geral, você pode converter entre todos os tipos numéricos em C #. Se não houver informações que serão perdidas durante o elenco, você poderá fazê-las implicitamente:
int i = 10;
decimal d = i;
embora você ainda possa fazê-lo explicitamente se desejar:
int i = 10;
decimal d = (decimal)i;
No entanto, se você estiver perdendo informações através do elenco, deve fazê-lo explicitamente (para mostrar que está ciente de que pode estar perdendo informações):
decimal d = 10.5M;
int i = (int)d;
Aqui você está perdendo o ".5". Isso pode ser bom, mas você deve ser explícito e fazer uma conversão explícita para mostrar que sabe que pode estar perdendo as informações.
ToEven
deve evitar desvios estatísticos. Se você, no entanto, opera com itens ou dinheiro a pagar, AwayFromZero
parece ser a escolha certa.
decimal vIn = 0.0M;
int vOut = Convert.ToInt32(vIn);
Aqui está uma página da Web de tipo de dados de conversão muito útil para as de outras pessoas. http://www.convertdatatypes.com/Convert-decimal-to-int-in-CSharp.html
System.Decimal
implementa a IConvertable
interface, que possui um ToInt32()
membro.
A chamada System.Decimal.ToInt32()
funciona para você?
Um bom truque para o arredondamento rápido é adicionar 0,5 antes de converter o decimal em int.
decimal d = 10.1m;
d += .5m;
int i = (int)d;
Ainda sai i=10
, mas
decimal d = 10.5m;
d += .5m;
int i = (int)d;
Arredondaria para que i=11
.
Prefiro usar Math.Round , Math.Floor , Math.Ceiling ou Math.Truncate para definir explicitamente o modo de arredondamento conforme apropriado.
Observe que todos eles retornam Decimal também - como o Decimal possui um intervalo maior de valores que um Int32, você ainda precisará converter (e verificar se há estouro / estouro).
checked {
int i = (int)Math.Floor(d);
}
Arredondando um decimal para o número inteiro mais próximo
decimal a ;
int b = (int)(a + 0.5m);
quando a = 49.9
entãob = 50
quando a = 49.5
entãob = 50
quando a = 49.4
, então b = 49
etc.
Acho que o operador de conversão não funciona se você tiver um decimal em caixa (ou seja, um valor decimal dentro de um tipo de objeto). Convert.ToInt32 (decimal como objeto) funciona bem nesse caso.
Essa situação surge ao recuperar valores de IDENTITY / AUTONUMBER do banco de dados:
SqlCommand foo = new SqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn);
int ID = Convert.ToInt32(foo.ExecuteScalar()); // works
int ID = (int)foo.ExecuteScalar(); // throws InvalidCastException
Consulte 4.3.2 Conversões de unboxing
SELECT SCOPE_IDENTITY()
retorna numeric(38, 0)
que é traduzido decimal
pelo .NET. foo.ExecuteScalar()
retorna uma decimal
caixa como a object
qual não pode ser convertida diretamente para uma int
. (int)(decimal)foo.ExecuteScalar()
ou Convert.ToInt32(foo.ExecuteScalar())
iria funcionar.
Nenhuma resposta parece lidar com a OverflowException / UnderflowException que vem da tentativa de converter um decimal que está fora do intervalo de int.
int intValue = (int)Math.Max(int.MinValue, Math.Min(int.MaxValue, decimalValue));
Esta solução retornará o valor int máximo ou mínimo possível se o valor decimal estiver fora do intervalo int. Você pode adicionar alguns arredondamentos com Math.Round, Math.Ceiling ou Math.Floor para quando o valor estiver dentro do intervalo int.