Por acaso nunca tinha necessitado mas pensava que existiria algo de framework que nos possibilitasse obter a parte decimal de um double. Bem aparentemente não existe nada, e o que encontrei na net achei um pouco complexo demais para a simplicidade do problema em si, logo fiz eu o seguinte código que acho não ser nada complicado e funciona em todas as situações (pelo menos as que testei).
public static int GetDecimalPart(double value) { int number = (int) value; string numbString = number.ToString(); int stringLength = numbString.Length; return Int32.Parse(value.ToString().Substring(stringLength+1)); }
9 comentários:
Não funciona se a parte decimal do double, depois de convertida, exceder a capacidade do int.
Math.Round ?
esquece o comentario anterior queres a parte decimal e n a inteira
Se o int não chegar podes sempre por um long :P
Isso é como tudo, se as tuas roupas não couberem no teu roupeiro tens de comprar um maior!
(nao é c#, mas deve ter uma função análoga)
return value - Math.floor(value);
Olá Tiago,
assim muito em cima do joelho, olha para os resultados deste código:
class Program
{
static void Main(string[] args)
{
double value = 1.123456789;
DateTime start = DateTime.UtcNow;
for (int i = 0; i < 10000; i++)
{
GetDecimalPartUsingDecimal(value);
}
Console.WriteLine(DateTime.UtcNow - start);
start = DateTime.UtcNow;
for (int i = 0; i < 10000; i++)
{
GetDecimalPartUsingMod(value);
}
Console.WriteLine(DateTime.UtcNow - start);
start = DateTime.UtcNow;
for (int i = 0; i < 10000; i++)
{
GetDecimalPartUsingString(value);
}
Console.WriteLine(DateTime.UtcNow - start);
Console.ReadLine();
}
private static decimal GetDecimalPartUsingDecimal(double value)
{
decimal myValuePrecision = Convert.ToDecimal(value);
return myValuePrecision - myValuePrecision - Decimal.Truncate(myValuePrecision);
}
private static double GetDecimalPartUsingMod(double value)
{
return value % 1;
}
public static int GetDecimalPartUsingString(double value)
{
int number = (int)value;
string numbString = number.ToString();
int stringLength = numbString.Length;
return Int32.Parse(value.ToString().Substring(stringLength + 1));
}
}
Para o André, o que eu quero é obter a parte decimal de um número só, para o número 1.123456789 eu quero como resultado 123456789 e não 0.123456789.
Para o Hugo, a tua 1ª função tinha um errinho mas eu percebi no return deveria estar myValuePrecision - Decimal.Truncate(myValuePrecision); e mais uma vez o teu resultado é igual ao do André apesar de demorar 1/3 do tempo da minha função.
Na 2ª função a nível de tempo é instantânea mas cuidado com o resultado que não é bem igual ao da 1ª função, se na 1ª obtinhas 0.123456789 aqui apanhas com os erros dos arredondamentos dos valores decimais e obtens 0.12345678900000001.
A 3ª função que é a minha retorna-me exactamente o que eu quero que foi o que expliquei ao André.
Já agora aumentei as iterações para 100000 e os resultados que obtive em ticks foram:
1ª - 781250
2ª - 0
3ª - 2343750
Olá Tiago,
Tira-me só uma dúvida, pelo teu código, a parte decimal de 1.02 será igual à parte decimal de 1.2...?
Abraços!
Sim sr. uma dúvida bastante inteligente :)
Eu à primeira diria que era 2 porque seria Int32.Parse("02");
Realmente já começo a perceber agora porque esta função não existe de framework, porque nestes casos o resultado é um pouco tricky(resultado 2 poderia ter como origem ,2 ,02 ,002...).
Contudo para as minhas necessidades não havia problema porque o meu primeiro digito decimal nunca era 0.
Enviar um comentário