Vous semblez avoir les avantages d'utiliser un type à virgule flottante. J'ai tendance à concevoir des décimales dans tous les cas, et je compte sur un profileur pour me faire savoir si les opérations sur les décimales provoquent des goulots d'étranglement ou des ralentissements. Dans ces cas, je vais "down cast" pour doubler ou flotter, mais seulement le faire en interne, et essayer soigneusement de gérer la perte de précision en limitant le nombre de chiffres significatifs dans l'opération mathématique effectuée.
En général, si votre valeur est transitoire (non réutilisée), vous pouvez utiliser un type à virgule flottante en toute sécurité. Le vrai problème avec les types à virgule flottante est les trois scénarios suivants.
- Vous agrégez des valeurs à virgule flottante (auquel cas les erreurs de précision sont composées)
- Vous créez des valeurs basées sur la valeur à virgule flottante (par exemple dans un algorithme récursif)
- Vous faites des calculs avec un très grand nombre de chiffres significatifs (par exemple,
123456789.1 * .000000000000000987654321
)
ÉDITER
Selon la documentation de référence sur les décimales C # :
Le mot-clé décimal désigne un type de données 128 bits. Comparé aux types à virgule flottante, le type décimal a une plus grande précision et une plage plus petite, ce qui le rend approprié pour les calculs financiers et monétaires.
Donc, pour clarifier ma déclaration ci-dessus:
J'ai tendance à concevoir des décimales dans tous les cas, et je compte sur un profileur pour me faire savoir si les opérations sur les décimales provoquent des goulots d'étranglement ou des ralentissements.
Je n'ai jamais travaillé que dans des industries où les décimales sont favorables. Si vous travaillez sur des moteurs phsyics ou graphiques, il est probablement beaucoup plus avantageux de concevoir un type à virgule flottante (float ou double).
Décimal n'est pas infiniment précis (il est impossible de représenter une précision infinie pour les non-intégrales dans un type de données primitif), mais il est beaucoup plus précis que double:
- décimal = 28-29 chiffres significatifs
- double = 15-16 chiffres significatifs
- float = 7 chiffres significatifs
EDIT 2
En réponse au commentaire de Konrad Rudolph , l'élément # 1 (ci-dessus) est définitivement correct. L'agrégation de l'imprécision aggrave en effet. 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();
}
Cela génère les éléments 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 constante de source, les résultats du double sont moins précis (bien que probablement arrondis correctement), et le flottant est beaucoup moins précis, au point où il a été réduit à seulement deux chiffres significatifs.