Vous semblez sur place avec les avantages de l'utilisation d'un type à virgule flottante. J'ai tendance à concevoir pour les décimales dans tous les cas, et s'appuient sur un profileur de me laisser savoir si les opérations sur les décimaux est à l'origine des goulots d'étranglement ou les ralentissements. Dans ces cas, je vais "en bas" jeté de lit double ou float, mais seulement le faire en interne, et soigneusement essayer de gérer la perte de précision due en limitant le nombre de chiffres significatifs dans l'opération mathématique à effectuer.
En général, si votre valeur est transitoire (pas réutilisé), vous êtes sûr d'utiliser un type à virgule flottante. Le vrai problème avec virgule flottante types est la suivante pour les trois scénarios.
- Vous l'agrégation des valeurs à virgule flottante (dans ce cas, les erreurs de précision composé)
- Vous construisez des valeurs basées sur la valeur à virgule flottante (par exemple dans un algorithme récursif)
- Vous êtes à faire des mathématiques avec un très grand nombre de chiffres significatifs (par exemple,
123456789.1 * .000000000000000987654321
)
MODIFIER
Selon la documentation de référence sur le C# décimales:
La virgule mot-clé indique un
128-bits type de données. Par rapport à
les types à virgule flottante, le type décimal
a une plus grande précision et une plus petite
la gamme, qui le rend approprié pour
monétaire et financier calculs.
Donc, pour clarifier ma déclaration ci-dessus:
J'ai tendance à concevoir pour les décimales dans tous les
cas, et de s'appuyer sur un profileur de laisser
- moi savoir si les opérations sur les décimaux est
provoquent des goulots d'étranglement ou les ralentissements.
Je n'ai jamais travaillé dans les industries où les décimales sont favorables. Si vous travaillez sur phsyics ou les moteurs graphiques, il est probablement beaucoup plus bénéfique pour la conception d'un type à virgule flottante (float ou double).
Virgule n'est pas infiniment précis (il est impossible de représenter une précision infinie pour les non-intégré dans un type de données primitif), mais il est beaucoup plus précis que le double:
- décimal = 28-29 chiffres significatifs
- double = 15 et 16 chiffres significatifs
- float = 7 chiffres significatifs
EDIT 2
En réponse à Konrad Rudolph's commentaire, le point n ° 1 (ci-dessus) est certainement correct. L'agrégation de l'imprécision n'est en effet composé. Voir le code ci-dessous pour un exemple:
private const float THREE_FIFTHS = 3f / 5f;
private const int ONE_MILLION = 1000000;
public static void Main(string[] args)
{
Console.WriteLine("Three Fifths: {0}", THREE_FIFTHS.ToString("F10"));
float asSingle = 0f;
double asDouble = 0d;
decimal asDecimal = 0M;
for (int i = 0; i < ONE_MILLION; i++)
{
asSingle += THREE_FIFTHS;
asDouble += THREE_FIFTHS;
asDecimal += (decimal) THREE_FIFTHS;
}
Console.WriteLine("Six Hundred Thousand: {0:F10}", THREE_FIFTHS * ONE_MILLION);
Console.WriteLine("Single: {0}", asSingle.ToString("F10"));
Console.WriteLine("Double: {0}", asDouble.ToString("F10"));
Console.WriteLine("Decimal: {0}", asDecimal.ToString("F10"));
Console.ReadLine();
}
Ce résultats suivants:
Three Fifths: 0.6000000000
Six Hundred Thousand: 600000.0000000000
Single: 599093.4000000000
Double: 599999.9999886850
Decimal: 600000.0000000000
Comme vous pouvez le voir, même si nous ajoutons à partir de la même source constante, les résultats de la double est moins précis (bien que probablement va s'arrondir correctement), et le flotteur est beaucoup moins précis, au point où il a été réduit à seulement deux chiffres significatifs.