3 votes

Convertir double en décimal

J'ai un problème de conversion de double en décimal :

 public class CartesianCoordinates
    {
        public int LatitudeHours { get; set;}
        public int LatitudeMinutes { get; set; }
        public int LatitudeSeconds { get; set; }
        public GeoDirectionLongtitude LongitudeDirection { get; set; }

        public int LongitudeHours { get; set; }
        public int LongitudeMinutes { get; set; }
        public int LongitudeSeconds { get; set; }
        public GeoDirectionLatitude LatitudeDirection { get; set; }
    }

public class DecimalCoordinates
    {
        public decimal Latitude { get; set; }
        public decimal Longitude { get; set; }
    }

CartesianCoordinates CartesianCoordinates=new CartesianCoordinates(){LatitudeHours =12,LatitudeMinutes =34,LatitudeSeconds=56 }

     converterDecimalCoordinates.Latitude = CartesianCoordinates.LatitudeHours + (CartesianCoordinates.LatitudeMinutes + (CartesianCoordinates.LatitudeSeconds / 60)) / 60;

Pourquoi j'obtiens 12 ? Je veux 12,55

9voto

David M Points 45808

Toutes vos calculs sont des entiers et sont arrondis (ou plus précisément, tronqués). Essayez de remplacer vos valeurs littérales de 60 par 60m pour forcer un calcul décimal, ou 60.0 pour forcer un calcul en double (auquel cas vous devrez convertir en décimal à la fin).

7voto

Daniel Brückner Points 36242
Int32 x = 10;

Decimal y = x / 4;  // Effectue une division entière - le résultat est 2.0
Decimal z = x / 4M; // Effectue une division décimale - le résultat est 2.25

Vous obtenez une division entière si les deux opérandes sont des entiers. En ajoutant le suffixe M à un nombre, vous pouvez indiquer explicitement que le nombre doit être interprété comme un nombre décimal et donc vous obtiendrez une division décimale.

3voto

Adam Houldsworth Points 38632

Vous obtenez 12 car le calcul est effectué sur des types int pour certaines parties et n'est donc pas capable de contenir la précision - la valeur est tronquée à un int. Je convertirais toutes vos valeurs en décimales avant de calculer - ou comme d'autres réponses l'ont suggéré, spécifiez vos littéraux comme des nombres décimaux.

Mise à jour : comme souligné dans d'autres publications, cela effectue actuellement une division entière - je n'étais pas au courant du terme technique, donc comme vous, j'ai appris quelque chose aujourd'hui lol

3voto

Abel Points 24335

En tant que résultat de ma discussion avec David M et Daniel Brückner sous cette réponse et de l'affirmation partiellement fausse de ma part sous cette réponse de Adam, il est devenu évident que, désolé de le dire, toutes les réponses ne sont que partiellement correctes. Ce qui se passe est le suivant :

// exemple (tous les x, y, z sont des entiers) :
Decimal d = x + y + z / 60M;

// est évalué de gauche à droite comme
Decimal d = x + y + (((Decimal) z) / 60M);

// lors de l'addition, voici ce qui se passe lorsque vous ajoutez des entiers et quelque chose d'autre :
Decimal d = x + y + (int) (((Decimal) z) / 60M);

// ce qui donnera un résultat tronqué.

Le résultat est : ajouter simplement un 60M ou 60.0 à toute la déclaration, comme cela a été suggéré, ne produira pas nécessairement le résultat voulu, en fonction de l'ordre d'exécution de la déclaration et/ou de l'existence d'additions/soustractions, comme c'est le cas dans la question de l'OP.

Pour corriger cela, suivez les conseils de Adam et convertissez chaque étape d'addition/soustraction en décimaux, utilisez des décimaux tout au long (pas très clair) ou placez le calcul dans une petite fonction qui prend des décimaux en tant que paramètres, forçant la conversion implicite :

Decimal GetDecimalLatitude(Decimal latitudeHours, Decimal latitudeMinutes, Decimal latitudeSeconds)
{
    return latitudeHours + (latitudeMinutes + (latitudeSeconds / 60)) / 60;
}

ce qui, en bonus, est plus court et améliore la lisibilité. Appelez cela avec la déclaration suivante :

converterDecimalCoordinates.Latitude = GetDecimalLatitude(
    CartesianCoordinates.LatitudeHours, 
    CartesianCoordinates.LatitudeMinutes,
    CartesianCoordinates.LatitudeSeconds);

1voto

Oliver Points 19006

Comme les autres l'ont déjà mentionné, vous avez de chaque côté de votre division un entier. Le résultat est donc également un entier (qui sera ensuite converti implicitement en décimal pour le côté gauche). Pour résoudre ce problème, un des côtés de votre division doit être un décimal, ce qui entraîne l'utilisation de la division décimale. Essayez simplement cette ligne de code :

converterDecimalCoordinates.Latitude = CartesianCoordinates.LatitudeHours + (CartesianCoordinates.LatitudeMinutes + (CartesianCoordinates.LatitudeSeconds / 60)) / (decimal)60;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X