Disons que j'ai une valeur de 3,4679 et que je veux 3,46, comment puis-je tronquer à deux décimales sans arrondir?
J'ai essayé ce qui suit mais les trois me donnent 3.47:
void Main()
{
Console.Write(Math.Round(3.4679, 2,MidpointRounding.ToEven));
Console.Write(Math.Round(3.4679, 2,MidpointRounding.AwayFromZero));
Console.Write(Math.Round(3.4679, 2));
}
Cela renvoie 3.46, mais semble juste sale comment:
void Main()
{
Console.Write(Math.Round(3.46799999999 -.005 , 2));
}
Il serait plus utile d'avoir une fonction complète pour une utilisation dans le monde réel de la troncature d'une décimale en C #. Cela pourrait être converti en une méthode d'extension Decimal assez facilement si vous le souhaitez:
Si vous avez besoin de VB.NET, essayez ceci:
Ensuite, utilisez-le comme ceci:
ou
la source
Utilisez l'opérateur module:
résultat: 0,54
la source
0.5400
... La réponse de D. Nesterov ci-dessous a produit le attendu0.54
.$"{0.54m:C}"
produit"$0.54"
et oui,$"{0.5400m:C}"
produit"$0.54"
.Méthode universelle et rapide (sans
Math.Pow()
/ multiplication) pourSystem.Decimal
:la source
Un problème avec les autres exemples est qu'ils multiplient la valeur d'entrée avant de la diviser. Il y a un cas de bord ici où vous pouvez déborder de décimal en multipliant d'abord, un cas de bord, mais quelque chose que j'ai rencontré. Il est plus sûr de traiter la partie fractionnaire séparément comme suit:
la source
Je laisserai la solution pour les nombres décimaux.
Certaines des solutions pour les décimales ici sont sujettes au débordement (si nous passons un très grand nombre décimal et que la méthode essaiera de le multiplier).
La solution de Tim Lloyd est protégée contre les débordements mais ce n'est pas trop rapide.
La solution suivante est environ 2 fois plus rapide et ne présente pas de problème de débordement:
la source
Truncate
méthode sera regroupée avec les méthodes natives .net, offrant à l'utilisateur une expérience transparente.Assert.AreEqual(1.1m, 1.12m.TruncateEx(1));
échoue à cause de cela. Si vous spécifiez un arrondi "normal" (AwayFromZero) dans l'appel Math.Round, puisAssert.AreEqual(0m, 0m.TruncateEx(1));
échoueMidpointRounding.AwayFromZero
et spécifiquement du code pour gérer la valeur 0.C'est une vieille question, mais de nombreuses réponses ne fonctionnent pas bien ou débordent pour de grands nombres. Je pense que la réponse de D. Nesterov est la meilleure: robuste, simple et rapide. Je veux juste ajouter mes deux cents. J'ai joué avec les décimales et j'ai également vérifié le code source . De la
public Decimal (int lo, int mid, int hi, bool isNegative, byte scale)
documentation du constructeur .Sachant cela, ma première approche a été d'en créer une autre
decimal
dont l'échelle correspond aux décimales que je voulais supprimer, puis de la tronquer et enfin de créer une décimale avec l'échelle souhaitée.Cette méthode n'est pas plus rapide que celle de D. Nesterov et elle est plus complexe, alors j'ai joué un peu plus. Je suppose que le fait de devoir créer un auxiliaire
decimal
et de récupérer les bits deux fois le ralentit. Lors de ma deuxième tentative, j'ai manipulé moi-même les composants retournés par la méthode Decimal.GetBits (Decimal d) . L'idée est de diviser les composants par 10 autant de fois que nécessaire et de réduire l'échelle. Le code est basé (fortement) sur la méthode Decimal.InternalRoundFromZero (ref Decimal d, int decimalCount) .Je n'ai pas effectué de tests de performances rigoureux, mais sur un processeur MacOS Sierra 10.12.6, Intel Core i3 3,06 GHz et ciblant .NetCore 2.1, cette méthode semble être beaucoup plus rapide que celle de D.Nesterov (je ne donnerai pas de chiffres depuis , comme je l'ai mentionné, mes tests ne sont pas rigoureux). Il appartient à quiconque implémente cela d'évaluer si les gains de performances sont récompensés par la complexité du code supplémentaire.
la source
cela fonctionnerait-il pour vous?
la source
Donnerait
((long)(3.4679 * 100)) / 100.0
ce que vous voulez?la source
Voici une méthode d'extension:
la source
Si vous ne vous inquiétez pas trop des performances et que votre résultat final peut être une chaîne, l'approche suivante sera résiliente aux problèmes de précision flottante:
la source
Voici mon implémentation de la fonction TRUNC
la source
Et ça?
la source
Outre les solutions ci-dessus, il existe un autre moyen de parvenir à ce résultat.
la source
Dans certaines conditions, cela peut suffire.
J'ai eu une valeur décimale de SubCent = 0,0099999999999999999999999999M qui a tendance à se formater à | SubCent: 0.010000 | via
string.Format("{0:N6}", SubCent );
et de nombreux autres choix de formatage.Mon exigence n'était pas d'arrondir la valeur SubCent, mais pas non plus de consigner chaque chiffre.
Les éléments suivants répondaient à mes exigences:
Qui renvoie la chaîne: | SubCent: 0,0099999 |
Pour accueillir la valeur ayant une partie entière, ce qui suit est un début.
Ce qui renvoie la chaîne:
la source
J'utilise cette fonction pour tronquer la valeur après la virgule dans une variable de chaîne
la source
C'est ce que j'ai fait:
soustraire deux nombres entrés sans arrondir les décimales vers le haut ou vers le bas. parce que les autres solutions ne fonctionnent pas pour moi. Je ne sais pas si cela fonctionnera pour les autres, je veux juste partager ceci :) J'espère que cela fonctionne pour ceux qui trouvent une solution à un problème similaire au mien. Merci
PS: je suis un débutant, alors n'hésitez pas à signaler quelque chose à ce sujet. : D c'est bien si vous traitez réellement avec de l'argent, à cause des cents non? il n'a que 2 décimales et son arrondi est un non non.
la source
la source
la source
En fait, vous voulez 3.46 de 3.4679. Il ne s'agit que d'une représentation de caractères. Il n'y a donc rien à voir avec la fonction mathématique. La fonction Math n'est pas destinée à faire ce travail. Utilisez simplement le code suivant.
la source
qu'en est-il de
la source