Comment déterminer si un décimal / double est un entier?

Comment savoir si une valeur décimale ou double est un entier?

Par exemple:

decimal d = 5.0; // Would be true decimal f = 5.5; // Would be false 

ou

 double d = 5.0; // Would be true double f = 5.5; // Would be false 

La raison pour laquelle j’aimerais savoir cela est que je peux déterminer par programmation si je veux sortir la valeur en utilisant .ToSsortingng("N0") ou .ToSsortingng("N2") . S’il n’y a pas de valeur décimale, alors je ne veux pas le montrer.

Pour les nombres à virgule flottante, n % 1 == 0 est généralement le moyen de vérifier s’il y a quelque chose qui dépasse le point décimal.

  public static void Main (ssortingng[] args) { decimal d = 3.1M; Console.WriteLine((d % 1) == 0); d = 3.0M; Console.WriteLine((d % 1) == 0); } 

Sortie:

 False True 

Mise à jour: Comme @Adrian Lopez mentionné ci-dessous, la comparaison avec une petite valeur epsilon éliminera les mauvais calculs de calcul en virgule flottante. Étant donné que la question concerne double valeurs double , la réponse ci-dessous sera une preuve de calcul à virgule flottante :

 Math.Abs(d % 1) <= (Double.Epsilon * 100) 

Il y a plusieurs façons de le faire. Par exemple:

 double d = 5.0; bool isInt = d == (int)d; 

Vous pouvez également utiliser modulo.

 double d = 5.0; bool isInt = d % 1 == 0; 

Que dis-tu de ça?

 public static bool IsInteger(double number) { return number == Math.Truncate(number); } 

Même code pour la decimal .

Mark Byers a fait un bon point, en fait: ce n’est peut-être pas ce que vous voulez vraiment . Si vous voulez vraiment savoir si un nombre arrondi à deux décimales près est un nombre entier , vous pouvez le faire à la place:

 public static bool IsNearlyInteger(double number) { return Math.Round(number, 2) == Math.Round(number); } 

Alors que les solutions proposées semblent fonctionner pour des exemples simples, le faire en général est une mauvaise idée. Un nombre peut ne pas être exactement un nombre entier, mais lorsque vous essayez de le formater, il est assez proche d’un nombre entier que vous obtenez 1.000000 . Cela peut se produire si vous faites un calcul qui, en théorie, devrait donner exactement 1, mais en pratique, vous obtenez un nombre très proche mais pas exactement égal à un en raison d’erreurs d’arrondi.

Au lieu de cela, formatez-le d’abord et si votre chaîne se termine par un point suivi de zéros, puis supprimez-les. Il existe également des formats que vous pouvez utiliser automatiquement pour cette bande. Cela pourrait être suffisant pour votre but.

 double d = 1.0002; Console.WriteLine(d.ToSsortingng("0.##")); d = 1.02; Console.WriteLine(d.ToSsortingng("0.##")); 

Sortie:

 1 1.02 
 bool IsInteger(double num) { if (ceil(num) == num && floor(num) == num) return true; else return false; } 

Problemo solvo.

Edit: Posté par Mark Rushakoff.

Si la limite supérieure et inférieure d’ Int32 importante:

 public bool IsInt32(double value) { return value >= int.MinValue && value <= int.MaxValue && value == (int)value; } 

La réponse de Mark Rushakoff peut être plus simple, mais ce qui suit fonctionne également et peut être plus efficace puisqu’il n’y a pas d’opération de division implicite:

  bool isInteger = (double)((int)f) == f ; 

et

  bool isInteger = (decimal)((int)d) == d ; 

Si vous voulez une seule expression pour les deux types, peut-être

  bool isInteger = (double)((int)val) == (double)val ; 

Vous pouvez utiliser le formatage de chaîne pour le type double. Voici un exemple:

 double val = 58.6547; Ssortingng.Format("{0:0.##}", val); //Output: "58.65" double val = 58.6; Ssortingng.Format("{0:0.##}", val); //Output: "58.6" double val = 58.0; Ssortingng.Format("{0:0.##}", val); //Output: "58" 

Faites-moi savoir si cela n’aide pas.

 static bool IsWholeNumber(double x) { return Math.Abs(x % 1) < double.Epsilon; } 

J’ai fait face à une situation similaire, mais la valeur est une chaîne. L’utilisateur saisit une valeur supposée être un montant en dollars, je veux donc valider qu’il est numérique et qu’il comporte au maximum deux décimales.

Voici mon code pour retourner true si la chaîne “s” représente un nombre numérique avec au plus deux décimales, et false sinon. Il évite tout problème résultant de l’imprécision des valeurs à virgule flottante.

 try { // must be numeric value double d = double.Parse(s); // max of two decimal places if (s.IndexOf(".") >= 0) { if (s.Length > s.IndexOf(".") + 3) return false; } return true; catch { return false; } 

J’en discute plus en détail à l’ adresse http://progblog10.blogspot.com/2011/04/determining-whether-numeric-value-has.html .

En utilisant int.TryParse, vous obtiendrez ces résultats: var shouldBeInt = 3;

  var shouldntBeInt = 3.1415; var iDontWantThisToBeInt = 3.000f; Console.WriteLine(int.TryParse(shouldBeInt.ToSsortingng(), out int parser)); // true Console.WriteLine(int.TryParse(shouldntBeInt.ToSsortingng(), out parser)); // false Console.WriteLine(int.TryParse(iDontWantThisToBeInt.ToSsortingng(), out parser)); // true, even if I don't want this to be int Console.WriteLine(int.TryParse("3.1415", out parser)); // false Console.WriteLine(int.TryParse("3.0000", out parser)); // false Console.WriteLine(int.TryParse("3", out parser)); // true Console.ReadKey(); 
  public static bool isInteger(decimal n) { return n - (Int64)n == 0; } 

Peut-être pas la solution la plus élégante mais ça marche si vous n’êtes pas trop pointilleux!

 bool IsInteger(double num) { return !num.ToSsortingng("0.################").Contains("."); } 

Vous pouvez utiliser la méthode ‘TryParse’.

 int.TryParse() 

Cela vérifie si la valeur peut être convertie en un nombre entier entier. Le résultat peut alors indiquer un indicateur qui peut être utilisé ailleurs dans votre code.

Essaye ça:

 number == Convert.ToInt16(number);