Ao ler o blog do Tiago vi uma solução que ele colocou para encontrar a parte decimal de um número usando C#.
À primeira vista pareceu-me que a solução dele era um pouco ingénua:
1: public static int GetDecimalPart(double value)
2: {
3: int number = (int) value;
4: string numbString = number.ToString();
5: int stringLength = numbString.Length;
6: return Int32.Parse(value.ToString().Substring(stringLength + 1));
7: }
Quer dizer, usar strings e Lenght’s? :S Não me parece que seja bom… Então decidi tentar fazer melhor … Esta foi a minha primeira iteração:
1: public static double GetDecimalPart2(double value)
2: {
3: return value % 1;
4: }
Ah! Genial, não é? Claro que já tinha um teste unitário à espera:
1: [Test]
2: public void CheckSimpleSolution()
3: {
4: Assert.AreEqual(0.02, DecimalTools.GetDecimalPart2(1.02));
5: }
Infelizmente o resultado não é o esperado:
Mas OK. Aqui o problema é que o double, que estamos a usar no GetDecimalPart2 não tem precisão suficiente para estas operações… Basta então tentar assim:
1: public static double GetDecimalPart2(double value)
2: {
3: return (double)(((decimal)value) % 1);
4: }
Basta converter o valor para um decimal que, tendo maior precisão, não perde valores na cálculo do ‘% 1′. Como o número original com que estou a trabalhar é um double no final posso voltar a converter para double, sem ter receio de encontrar uma excepção. Correndo o teste:
Excelente… Mas… vendo o código original… o retorno é um inteiro! Isso quer dizer que o valor de retorno de um argumento de 1.02 seria 2, em vez de 0.02. Mas isso também seria o resultado de 1.2… Tenho de ver:
1: [Test]
2: public void CheckOriginalForDuplicateResults()
3: {
4: Assert.AreNotEqual(DecimalTools.GetDecimalPart(1.2), DecimalTools.GetDecimalPart(1.02));
5: }
Ouch… Ao que parece, enganei-me nos requisitos… Pela implementação do Tiago, vejo que ele quer algo completamente diferente. Vejam a seguinte tabela:
| Valor Original | GetDecimalPart | GetDecimalPart2 |
| 1.02 | 2 | 0.02 |
| 1.2 | 2 | 0.2 |
| 1 | 0 | 0.0 |
Apesar do que se pretendido no GetDecimalPart não me fazer sentido, se isso é mesmo o desejado, não me lembro de nenhuma implementação que seja melhor que a do Tiago…
Agora acho que deviam ir ao site dele dizer quanto admiram o código dele e deixarem aqui uns comentários para me dizerem o quanto me odeiam por vos ter feito perder este tempo todo

No comments yet
Comentários feed para este artigo