Comment convertir une décimale en int?
Comment convertir une décimale en int?
Réponses:
Utilisez Convert.ToInt32
de mscorlib
comme
decimal value = 3.14m;
int n = Convert.ToInt32(value);
Voir MSDN . Vous pouvez également utiliser Decimal.ToInt32
. Encore une fois, voir MSDN . Enfin, vous pouvez faire un cast direct comme dans
decimal value = 3.14m;
int n = (int) value;
qui utilise l'opérateur de transtypage explicite. Voir MSDN .
null
vs. 0
vs. ""
). Je recommanderais de ne jamais utiliser Convert, sauf si vous avez absolument besoin de sa flexibilité (c'est-à-dire dans des scénarios typés dynamiquement)
OverflowException
. Je crois que @Will fournit une meilleure réponse ici stackoverflow.com/a/501165/39532
Convert.ToInt32
et Decimal.ToInt32
comportez-vous différemment. À partir de MSDN: Decimal.ToInt32
- La valeur de retour fait partie intégrante de la valeur décimale; les chiffres fractionnaires sont tronqués . Convert.ToInt32
- Renvoie la valeur arrondie à l'entier signé 32 bits le plus proche. Si la valeur est à mi-chemin entre deux nombres entiers, le nombre pair est renvoyé; c'est-à-dire que 4,5 est converti en 4 et 5,5 est converti en 6.
Tu ne peux pas.
Bien sûr, vous pourriez , cependant, un int (System.Int32) n'est pas assez grand pour contenir toutes les valeurs décimales possibles.
Cela signifie que si vous transtypez une décimale plus grande que int.MaxValue, vous déborderez et si la décimale est plus petite que int.MinValue, elle dépassera.
Que se passe-t-il lorsque vous débordez / débordez? Une des deux choses. Si votre build n'est pas coché (c'est-à-dire que le CLR s'en fiche si vous le faites), votre application continuera après la valeur over / underflows, mais la valeur dans l'int ne sera pas celle que vous attendiez. Cela peut entraîner des bogues intermittents et peut être difficile à corriger. Vous finirez votre application dans un état inconnu, ce qui peut entraîner la corruption de votre application, quelles que soient les données importantes sur lesquelles elle travaille. Pas bon.
Si votre assemblage est vérifié (propriétés-> build-> avancé-> vérifier le dépassement / sous-dépassement arithmétique ou l'option de compilateur / vérifié), votre code lèvera une exception lorsqu'un sous-dépassement / dépassement se produira. C'est probablement mieux qu'improbable; cependant, la valeur par défaut pour les assemblages n'est pas de vérifier les débordements / débordements.
La vraie question est "qu'essayez-vous de faire?" Sans connaître vos besoins, personne ne peut vous dire ce que vous devez faire dans ce cas, autre que l'évidence: NE PAS FAIRE.
Si vous ne vous souciez pas spécifiquement, les réponses ici sont valides. Cependant, vous devez communiquer votre compréhension qu'un débordement peut se produire et que cela n'a pas d'importance en enveloppant votre code de distribution dans un bloc non contrôlé
unchecked
{
// do your conversions that may underflow/overflow here
}
De cette façon, les gens qui vous suivent comprennent que vous ne vous souciez pas, et si à l'avenir quelqu'un change vos versions en / vérifié, votre code ne se cassera pas de manière inattendue.
Si tout ce que vous voulez faire est de supprimer la partie fractionnaire du nombre, en laissant la partie intégrale, vous pouvez utiliser Math.Truncate.
decimal actual = 10.5M;
decimal expected = 10M;
Assert.AreEqual(expected, Math.Truncate(actual));
int i = (int)d;
vous donnera le nombre arrondi.
Si vous voulez arrondir au nombre pair le plus proche (c'est-à-dire> .5 arrondira), vous pouvez utiliser
int i = (int)Math.Round(d, MidpointRounding.ToEven);
En général, vous pouvez effectuer un cast entre tous les types numériques en C #. S'il n'y a aucune information qui sera perdue pendant la distribution, vous pouvez le faire implicitement:
int i = 10;
decimal d = i;
mais vous pouvez toujours le faire explicitement si vous le souhaitez:
int i = 10;
decimal d = (decimal)i;
Cependant, si vous allez perdre des informations via le casting, vous devez le faire explicitement (pour montrer que vous êtes conscient que vous risquez de perdre des informations):
decimal d = 10.5M;
int i = (int)d;
Ici, vous perdez le ".5". Cela peut être bien, mais vous devez être explicite à ce sujet et faire un casting explicite pour montrer que vous savez que vous perdez peut-être les informations.
ToEven
devrait empêcher la dérive des statistiques. Si vous opérez cependant avec des articles payants ou de l'argent, cela AwayFromZero
semble être le bon choix.
decimal vIn = 0.0M;
int vOut = Convert.ToInt32(vIn);
Voici une page Web de type de données de conversion très pratique pour celles des autres. http://www.convertdatatypes.com/Convert-decimal-to-int-in-CSharp.html
System.Decimal
implémente l' IConvertable
interface, qui a un ToInt32()
membre.
L'appel System.Decimal.ToInt32()
vous convient-il?
Une astuce intéressante pour un arrondi rapide consiste à ajouter 0,5 avant de convertir votre décimale en entier.
decimal d = 10.1m;
d += .5m;
int i = (int)d;
Part toujours i=10
, mais
decimal d = 10.5m;
d += .5m;
int i = (int)d;
Arrondirait ainsi i=11
.
Je préfère utiliser Math.Round , Math.Floor , Math.Ceiling ou Math.Truncate pour définir explicitement le mode d'arrondi comme il convient.
Notez qu'ils renvoient tous également Decimal - puisque Decimal a une plus grande plage de valeurs qu'un Int32, vous devrez donc toujours caster (et vérifier le débordement / le débordement).
checked {
int i = (int)Math.Floor(d);
}
Arrondir une décimale à l'entier le plus proche
decimal a ;
int b = (int)(a + 0.5m);
quand a = 49.9
, alorsb = 50
quand a = 49.5
, alorsb = 50
quand a = 49.4
, alors b = 49
etc.
Je trouve que l'opérateur de casting ne fonctionne pas si vous avez une décimale encadrée (c'est-à-dire une valeur décimale à l'intérieur d'un type d'objet). Convert.ToInt32 (décimal en tant qu'objet) fonctionne correctement dans ce cas.
Cette situation se produit lors de la récupération des valeurs IDENTITY / AUTONUMBER de la base de données:
SqlCommand foo = new SqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn);
int ID = Convert.ToInt32(foo.ExecuteScalar()); // works
int ID = (int)foo.ExecuteScalar(); // throws InvalidCastException
SELECT SCOPE_IDENTITY()
retours numeric(38, 0)
qui se traduisent decimal
par .NET. foo.ExecuteScalar()
renvoie un cadre decimal
comme object
qui ne peut pas être converti directement en un int
. (int)(decimal)foo.ExecuteScalar()
ou Convert.ToInt32(foo.ExecuteScalar())
fonctionnerait.
Aucune réponse ne semble traiter de l'OverflowException / UnderflowException qui vient d'essayer de convertir une décimale qui est en dehors de la plage d'int.
int intValue = (int)Math.Max(int.MinValue, Math.Min(int.MaxValue, decimalValue));
Cette solution renverra la valeur int maximale ou minimale possible si la valeur décimale est en dehors de la plage int. Vous voudrez peut-être ajouter un arrondi avec Math.Round, Math.Ceiling ou Math.Floor lorsque la valeur se trouve dans la plage int.