0
votes

Chaîne ronde avant de convertir au type numérique

J'ai un numéro (juste un exemple: xxx

stocké dans une chaîne . Je veux le convertir en décimal mais Obtenez une OverflowException car la valeur est trop longue pour la décimale.

Je veux rond la chaîne avant de la convertir avant de la convertir < em> pour fixer l'erreur .

Comment puis-je faire cela?


10 commentaires

L'avez-vous essayé? S'il vous plaît fournir votre code. Alors vous aidera si vous êtes coincé, mais ce n'est pas un code fournissant un code.


Comment le convertissez-vous? décimal.parse ("3616.9464896538020822229190750632226") fonctionne sur ma machine, tandis que décimal.parse ("3616,94648965380750632229190750632229190750632229190750632229190750632229190750632229190750632226") me donne un formatexception parce que Le , est interprété comme un séparateur de milliers, mais un overflowException n'est pas dans les cartes.


J'ai essayé de convertir votre échantillon en utilisant convert.todecimal ("...") et il le convertit correctement. Je reçois seulement un OverflowException , lorsque le numéro est trop gros pour un décimal ...


quel est le résultat attendu? Devrait-il être 3616.9464896538020822299190751 ?


@Nicoschreiner êtes-vous sûr? DOTNETFIDDLE.net/0UU1RK - Il produit l'erreur indiquée dans la question. Si vous changez la virgule à un point, alors c'est bon: DotNetFiddle.net/828RXL . Est-ce ce que tu as fait?


résultat décimal = décimal.parse (source, nouveau numéroFormatinfo () {NumberDecimalseparator = ","});


@Adyson Oui, ça fait. Copier collé le code que vous avez lié à VS et il le convertit à 3616.9464896538020822299190751. Ahh le problème est la culture ...


@Nicoschreiner Avez-vous eu une culture différente dans votre application peut-être?


@Adyson Oui La culture est le problème. Ma culture est de-de-de et nous utilisons ',' comme séparateur.


@Nicoschreiner qui l'explique alors. Peut-être que c'est quelque chose qui vaut la peine d'être écrit comme une réponse - OP pourrait dépasser le cadre de la culture dans leur application dont ils auraient besoin, s'ils veulent faire face à ce type de format en standard. Ou ils pourraient préférer l'une des réponses ci-dessous où elles sont hard-codez le séparateur dans le code afin de traiter cela comme si c'est un cas particulier. Je pense montrer comment définir la culture et ensuite faire la conversion comme normale doit être une option valide ici.


4 Réponses :


6
votes

L'analyse est spécifique à la culture. Donc, , peut être une décimale ou des milliers de séparateur. Si , est mille séparateur, il sera ignoré : xxx

et cette valeur est sur décimal.maxvalue Vous avez donc la exception .

si , doit être traité comme séparateur décimal, le système le savoir: xxx

et vous obtiendrez < Code> 3616.9464896538020822299190751M


0 commentaires

2
votes

Votre problème n'est pas un problème d'arrondi, il essaie d'analyser une décimale avec une virgule sur un système qui attend un point de séparateur décimal par défaut.

Vous pouvez essayer cela pour vous assurer qu'il est bien analysé Sur tous les environnements: xxx

https://dotnetfiddle.net/8iori9d


0 commentaires

0
votes

Compte tenu d'un nombre arbitraire de décimales dans un format avec une virgule séparant les unités de la partie fractionnée, vous pouvez le résoudre en procédant comme suit:

class Program
{
    static void Main(string[] args)
    {
        var decimalPlacesCount = 10;
        var decimalSeparator = ',';
        var parts = "3616,946489653802082229919075063226".Split(decimalSeparator);
        var value = decimal.Parse(parts[0]);
        if (parts.Length == 2)
        {
            value += decimal.Parse($"0.{parts[1].Substring(0, decimalPlacesCount)}");
        }
        Console.WriteLine(value);
    }
}


0 commentaires

0
votes

Bien que ce n'était pas votre problème si quelqu'un se passe survolez cette question bien nommée à la recherche d'une méthode qui fera une ficelle, ce qui sera utile, les suivants seront utiles.

    public static string RoundString(string value, int decimalPlaces)
    {
        StringBuilder returnValue = new StringBuilder(value);

        int startIndex = 0;

        int charIndex = 0;
        while (charIndex < value.Length && startIndex == 0)
        {
            if (value[charIndex].ToString() == ".")
                startIndex = charIndex + 1;

            charIndex++;
        }

        if (int.Parse(value[charIndex + decimalPlaces + 1].ToString()) >= 5)
        {
            bool rounded = false;
            for (charIndex = startIndex + decimalPlaces; charIndex > -1; charIndex--)
            {
                if (!rounded && charIndex != startIndex-1)
                { 
                    int newVal = int.Parse(returnValue[charIndex].ToString()) + 1;
                    if (newVal > 9)
                    {
                        returnValue[charIndex] = '0';
                    }
                    else
                    {
                        returnValue[charIndex] = (int.Parse(returnValue[charIndex].ToString()) + 1).ToString()[0];
                        rounded = true;
                    }
                }
            }
            if (!rounded)
            {
                startIndex++;
                returnValue = new StringBuilder("1" + returnValue.ToString());
            }
        }

        return returnValue.ToString().Substring(0, startIndex + decimalPlaces);
    }


0 commentaires