Este post nasce de uma burrice minha porque olhei para um pedaço de código simplesmente com olhar matemático, o código exemplo é o seguinte:
int total = 40000;
int toDiv = 100;
double var1 = (toDiv/total)*100;
double var2 = (toDiv*100/total);
double var3 = (double)toDiv / total * 100;
Console.WriteLine("Valor1 = {0}", var1.ToString("0.000"));
Console.WriteLine("Valor2 = {0}", var2.ToString("0.000"));
Console.WriteLine("Valor3 = {0}", var3.ToString("0.000"));
Console.Read();
Quando estava a fazer o meu algoritmo fiz algo idêntico ao que está em var1, uma divisão é um valor e pronto, não há nada de extraordinário pensei eu, resultado da divisão 0,000. Ok o valor é demasiado baixo pensei eu e a divisão arredonda para 0.
Não contente com a estupidez original aqui vai mais outra a da var2, se o valor é pequeno faço a multiplicação primeiro e assim o dividendo já é maior já não irá dar 0 pensei eu, resultado um 0,000, equivalente a 'és um 0 à esquerda'.
Finalmente olhei para aquilo não como mau matemático que sou, mas como programador e aí apareceu o código do var3, o problema é estar a dividir duas variáveis do tipo int cujo resultado também é um int que só na afectação é convertido para double implicitamente. Logo o truque é forçar que uma das variáveis seja um double para o resultado da divisão ser um double. Ai, ai, ai às vezes tenho destes dias...