Comment puis-je convertir un double en la valeur entière la plus proche?

147

Comment convertir un double en int le plus proche?

Léora
la source

Réponses:

78

Utiliser Math.round(), éventuellement en conjonction avecMidpointRounding.AwayFromZero

par exemple:

Math.Round(1.2) ==> 1
Math.Round(1.5) ==> 2
Math.Round(2.5) ==> 2
Math.Round(2.5, MidpointRounding.AwayFromZero) ==> 3
nickf
la source
6
Ne Convert.ToInt32()fera- t-il pas la même chose ou supprimera-t-il simplement tout après la virgule?
The Muffin Man
208
Ne produit pas réellement un entier, mais un double.
gatopeich
13
@Ronnie - non, c'est par conception. Par défaut, Math.Round arrondira les nombres du milieu (x + 0,5) au nombre pair le plus proche . Si vous voulez un comportement différent, vous devez le spécifier via un drapeau. msdn.microsoft.com/en-us/library/system.midpointrounding.aspx
nickf
6
Eh bien je n'ai jamais! :)
Ronnie
5
Double n'est pas Int.
Evgeni Nabokov
267
double d = 1.234;
int i = Convert.ToInt32(d);

Référence

Gère les arrondis comme ceci:

arrondi à l'entier signé 32 bits le plus proche. Si la valeur est à mi-chemin entre deux nombres entiers, le nombre pair est renvoyé; autrement dit, 4,5 est converti en 4 et 5,5 est converti en 6.

John Sheehan
la source
7
Beaucoup mieux que Math.Roundcar il renvoie un int comme requis.
Keith
10
@ robert-koritnik. Je ne sais pas pourquoi c'est "invalide". OP n'a pas spécifié de règle d'arrondi préférée, et "arrondir 0,5 au plus proche pair" est la règle standard de retour. Arrondir toujours a des effets statistiques indésirables.
Keith
@Keith: Je ne sais pas mais on m'a toujours appris à arrondir x.5 mais je peux voir un raisonnement pour le faire à la hausse ou à la baisse pour les statistiques. Merci pour ça. PS Il est clair que je ne suis pas dans les statistiques, les finances ou la comptabilité où ce genre d'arrondi semble être par défaut .
Robert Koritnik
3
«Toujours arrondir a des effets statistiques indésirables» - C'est tout simplement faux. Arrondir 0,5 vers le haut arrondit exactement la moitié des nombres - [0,.5)- vers le bas et exactement la moitié des nombres - [.5,1)- vers le haut. Arrondir à même légèrement biaiser les nombres pairs, car il arrondit (.5,1.5)à 1 mais [1.5,2.5]à 2.
Jim Balter
11
@JimBalter Comme le zéro n'est pas arrondi, arrondir à la moitié introduit un biais positif, il est donc connu sous le nom d'arrondi asymétrique. Le «arrondi de moitié à pair» ne le fait pas, si votre distribution est suffisante et que l'arrondi ne biaise ni les nombres pairs ni les nombres impairs. Voir le bris d'égalité à mi-chemin .
sdds
36

Vous pouvez également utiliser la fonction:

//Works with negative numbers now
static int MyRound(double d) {
  if (d < 0) {
    return (int)(d - 0.5);
  }
  return (int)(d + 0.5);
}

Selon l'architecture, c'est plusieurs fois plus rapide.

szymcio
la source
C'était parfait pour moi car Math.Round ne fonctionnait pas comme je le voulais.
Hanna
@cullub oui. Il convertit le double d auquel était ajouté 0,5 en un entier.
Darrell
C'est ma méthode préférée - fonctionne de manière très simple. Tellement plus court et plus facile à lire que Math.Round (d, MidpointRounding.AwayFromZero) et plus concis que d'utiliser une instruction if pour choisir d'arrondir ou d'arrondir vers le haut. AND, renvoie en fait un entier à la fin, pas un double
lié
3
Voir le commentaire de @ Eternal21 ci-dessous pour un comportement impair sur les nombres négatifs (MyRound (-1,2) = 0)
Chris
2
Pour quiconque se demande, le problème mentionné par @Chris est maintenant vraisemblablement résolu en vérifiant si la valeur est négative.
John Weisz
14
double d;
int rounded = (int)Math.Round(d);

la source
5

Je sais que cette question est ancienne, mais je l'ai rencontrée en cherchant la réponse à ma question similaire. J'ai pensé partager le conseil très utile qui m'a été donné.

Lors de la conversion en int, ajoutez simplement .5à votre valeur avant le downcasting. Comme le downcasting inttombe toujours au nombre inférieur (par exemple (int)1.7 == 1), si votre nombre est .5ou supérieur, l'ajout .5le ramènera au nombre suivant et votre downcast intdevrait renvoyer la valeur correcte. (par exemple (int)(1.8 + .5) == 2)

Trent
la source
13
Le problème est que vous essayez de convertir des valeurs négatives de cette façon. Par exemple, -1,25 sera égal à 0. (-1,25 + 0,5 = 0,75, et une fois converti en int, il vaut 0). Vous devez donc soustraire 0,5 des valeurs négatives.
Eternal21
On peut utiliser+ 0.5 * Math.Abs(d)
TaW
-1

Pour Unity, utilisez Mathf.RoundToInt .

using UnityEngine;

public class ExampleScript : MonoBehaviour
{
    void Start()
    {
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.0f));
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.2f));
        // Prints 11
        Debug.Log(Mathf.RoundToInt(10.7f));
        // Prints 10
        Debug.Log(Mathf.RoundToInt(10.5f));
        // Prints 12
        Debug.Log(Mathf.RoundToInt(11.5f));

        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.0f));
        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.2f));
        // Prints -11
        Debug.Log(Mathf.RoundToInt(-10.7f));
        // Prints -10
        Debug.Log(Mathf.RoundToInt(-10.5f));
        // Prints -12
        Debug.Log(Mathf.RoundToInt(-11.5f));
    }
}

La source

public static int RoundToInt(float f) { return (int)Math.Round(f); }
zwcloud
la source
Q ne mentionne ni ne marque Unity.
XenoRo
@XenoRo Je répondais à cette vieille question pour ceux qui recherchaient des réponses similaires en utilisant Unity.
zwcloud
2
Vous pouvez répondre à vos propres questions pour le partage des connaissances. Créez une question distincte spécifique à l'API (dans ce cas, Unity) dans des cas comme celui-ci. Les réponses doivent être adaptées aux questions. Sinon, il pourrait y avoir une réponse ici pour chaque API C # avec une fonction d'arrondi.
XenoRo
-2

Je développe une calculatrice scientifique qui arbore un bouton Int. J'ai trouvé ce qui suit est une solution simple et fiable:

double dblInteger;
if( dblNumber < 0 )
   dblInteger = Math.Ceiling(dblNumber);
else
   dblInteger = Math.Floor(dblNumber);

Math.Round produit parfois des résultats inattendus ou indésirables, et la conversion explicite en entier (via cast ou Convert.ToInt ...) produit souvent des valeurs erronées pour les nombres de plus haute précision. La méthode ci-dessus semble toujours fonctionner.

Mark Jones
la source
2
n'est-ce pas arrondir tous les nombres négatifs et arrondir tous les nombres positifs? Ce n'est pas nécessairement l'entier le plus «net».
Tim Pohlmann
ce n'est pas le nombre le plus proche.
Samer Aamar
1
Étant donné 1,99, cela renvoie 1,0.
Jon Schneider