2010-08-03 9 views
13

Quelle est la meilleure façon de prendre une chaîne qui peut être vide ou contenir "1.2" par exemple, et la convertir en entier? int.TryParse échoue, bien sûr, et je ne veux pas utiliser float.TryParse, puis convertir en int.C# Conversion d'une chaîne contenant un nombre à virgule flottante en entier

+0

BTW, 1.2 est pas un entier . – Zaki

+4

En l'analysant à un flotteur et puis en le montant, je ne vois pas comment vous pourriez faire cela ... – Philippe

+1

'(int) float.Parse (" 1.2 ")' - ce n'est pas trop de travail. Ruby le fait cependant - '" 1.234 ".to_i' donne 1 – Gishu

Répondre

33

Solution 1: Convert.ToDouble (dépendant de la culture)

Vous pouvez à l'aide Convert.ToDouble. Mais méfiez-vous! La solution ci-dessous ne fonctionnera que lorsque le séparateur de nombres dans le réglage de la culture actuelle est un caractère de période.

var a = (int)Convert.ToDouble("1.2");  

Solution 2: Convert.ToDouble (indépendant culture)

Il est préférable d'utiliser IFormatProvider et convertir le nombre d'une manière indépendante des paramètres de culture actuels:

var a = (int)Convert.ToDouble("1.2", CultureInfo.InvariantCulture.NumberFormat); 

Solution 3: Parse & Division

Une autre façon d'accomplir cette tâche consiste à utiliser Split sur une chaîne analysée:

var a = int.Parse("1.2".Split('.')[0]); 

Ou:

var a = int.Parse("1.2".Split('.').First()); 

Notes de

+2

+1. Spécifiquement pour dire que 'Convert.ToDouble' utilise le délimiteur décimal des paramètres de culture de thread (par défaut les paramètres régionaux de Windows), et il peut s'agir d'une virgule. Vous pouvez le forcer à utiliser un point en passant 'CultureInfo.InvariantCulture.NumberFormat' – MarkJ

1

Peut-être que vous pouvez essayer de tout supprimer après virgule flottante en utilisant des fonctions de chaîne, puis convertir en int. Mais sérieusement, je ne pense pas que ce soit mieux que de convertir en float puis en int.

+0

Si vous le faites de cette façon, n'oubliez pas que le délimiteur décimal est différent sur les différents paramètres régionaux. Nos cousins ​​français utilisent ',' – MarkJ

+0

Bien sûr, je pensais que c'était évident :) En Russie, nous utilisons également des virgules. – fuwaneko

4

Je ne sais pas ce qui ne va pas avec l'analyse syntaxique à un float et la conversion à un int. Je doute que tout autre moyen serait plus efficace mais voici une tentative:

//allows empty strings and floating point values 
int ParseInt(string s, bool alwaysRoundDown = false) 
{ 
    //converts null/empty strings to zero 
    if (string.IsNullOrEmpty(s)) return 0; 

    if (!s.Contains(".")) return int.Parse(s); 

    string parts = s.Split("."); 
    int i = int.Parse(parts[0]); 
    if (alwaysRoundDown || parts.Length==1) return i; 

    int digitAfterPoint = int.Parse(parts[1][0]); 
    return (digitAfterPoint < 5) ? i : i+1; 
} 

Pour mondialiser le code que vous devrez remplacer "." avec System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator.

+0

N'oubliez pas que le délimiteur décimal peut être différent en fonction des paramètres régionaux. – MarkJ

+0

J'ai ajouté une note sur la mondialisation. Merci! –

+0

Sans aucun doute le meilleur, @Mark. +1 de mon côté. – Kangkan

0

Je pense qu'une autre façon de le faire serait de diviser la chaîne en morceaux en prenant la décimale (.) Comme délimiteur, puis en analysant l'entier. Bien sûr, je ne suis pas encore à vous demander si la chaîne peut contenir des valeurs comme "37.56 miles in 32.65 seconds" valeurs de type.

vu qu'il n'y aura qu'une seule valeur (chaîne ou nombre) dans la chaîne, je peux penser à quelque chose dans la ligne suivante:

public int64 GetInt64(string input) 
{ 
    if (string.IsNullOrEmpty(input)) return 0; 
    // Split string on decimal (.) 
    // ... This will separate all the digits. 
    // 
    string[] words = input.Split('.'); 
    return int.Parse(words[0]); 
} 
+0

Peut-être pas besoin de retour int64 lors d'une analyse int32. – btlog

1
int a = (int)Math.Round(float.Parse("0.9")); 

Vous devez arrondir d'abord, sauf si vous voulez 0,9 f en cours de conversion à 0 au lieu de 1.

0

Vous pouvez utiliser la bibliothèque d'exécution Visual Basic pour accomplir cela à partir de C#.

Vous devez ajouter une référence à l'assembly Microsoft.VisualBasic.dll à votre solution.

ensuite le code suivant fera votre conversion:

using VB = Microsoft.VisualBasic.CompilerServices; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     int i = VB.Conversions.ToInteger("1.2"); 
    } 
} 
0

J'ai eu ce même problème et a fini par utiliser un hybride de Marc et Dariusz ':

if (num == "") 
    { 
     num = "0.00"; 
    } 

    var num1 = (float)Convert.ToDouble(num);