75 votes

À quoi sert Decimal.One, Decimal.Zero, Decimal.MinusOne en .Net ?

Question simple : pourquoi le type Decimal définit-il ces constantes ? Pourquoi s'en préoccuper ?

Je cherche une raison pour laquelle ceci est défini par le langage, et non pas des utilisations possibles ou des effets sur le compilateur. Pourquoi le mettre là en premier lieu ? Le compilateur peut tout aussi bien mettre 0m en ligne que Decimal.Zero, donc je ne crois pas que ce soit un raccourci pour le compilateur.

3 votes

Je ne pense pas que ces réponses expliquent de manière adéquate pourquoi ces valeurs sont présentes. J'entends certains effets et usages, mais ce que je cherche, c'est POURQUOI cela a été conçu dans le langage, et pourquoi ce n'est pas là dans Float, par exemple, ou Int32...

0 votes

Ils aident les compilateurs à générer des assemblages plus compacts. Toujours utilisé aujourd'hui

38voto

JaredPar Points 333733

Petite précision. Il s'agit en fait de valeurs statiques en lecture seule et non de constantes. Il y a une différence distincte dans .Net, car les valeurs constantes sont en ligne par les différents compilateurs et il est donc impossible de suivre leur utilisation dans un assemblage compilé. Les valeurs statiques en lecture seule ne sont pas copiées mais référencées. C'est un avantage pour votre question car cela signifie que l'utilisation de ces valeurs peut être analysée.

Si vous utilisez reflector et que vous fouillez dans la BCL, vous remarquerez que MinusOne et Zero ne sont utilisés que dans le runtime VB. Ils existent principalement pour servir les conversions entre les valeurs décimales et booléennes. La raison pour laquelle MinusOne est utilisé a été abordée par hasard dans un autre fil de discussion aujourd'hui même ( lien )

Curieusement, si vous regardez la valeur Decimal.One, vous remarquerez qu'elle n'est utilisée nulle part.

Quant à savoir pourquoi ils sont explicitement définis ... Je doute qu'il y ait une raison précise. Il y a apparaît de n'avoir aucune performance spécifique et seulement un peu de mesure de commodité que l'on peut attribuer à leur existence. Mon devinez est qu'ils ont été ajoutés par quelqu'un pendant le développement de la BCL pour leur confort et n'ont jamais été retirés.

EDITAR

Creusé dans le const émettre un peu plus après un commentaire de @Paleta. La définition C# de Decimal.One utilise le const mais il est émis comme un static readonly au niveau de l'IL. Le compilateur C# utilise quelques astuces pour rendre cette valeur pratiquement indiscernable d'une valeur const (inline les littéraux par exemple). Cela apparaîtrait dans un langage qui reconnaît cette astuce (VB.Net la reconnaît mais pas F#).

1 votes

Il est incorrect que ces valeurs soient en lecture seule, en regardant la métadonnée Decimal du cadre .net, vous pouvez voir ce qui suit [DecimalConstant(0, 0, 4294967295, 4294967295, 4294967295)] public const decimal MaxValue = 79228162514264337593543950335m ; [DecimalConstant(0, 128, 0, 0, 1)] public const decimal MinusOne = -1m ;

1 votes

@Paleta, non ils sont readonly . J'ai vérifié cela en regardant les métadonnées et la page MSDN pour les valeurs. msdn.microsoft.com/fr/us/library/system.decimal.one(VS.80).aspx

1 votes

Je ne suis pas d'accord avec vous et votre réponse, regardez le code reflété de mscorlib.dll ici reflector.webtropy.com/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/ Ceux-ci sont déclarés comme des constantes, MSDN est incorrect.

24voto

mihi Points 3476

Certains langages .NET ne prennent pas en charge les littéraux décimaux, et il est plus pratique (et plus rapide) dans ces cas d'écrire Decimal.ONE au lieu de new Decimal(1).

La classe BigInteger de Java possède également ZERO et UN, pour la même raison.

1 votes

Quelqu'un peut-il m'expliquer cela ? 6 votes positifs signifient que c'est une bonne réponse, mais.. : Comment un langage .Net qui ne prend pas en charge les décimales comme type de données peut-il bénéficier d'une propriété partagée en lecture seule qui renvoie une décimale et qui est définie comme faisant partie de la classe décimale ?

9 votes

Il voulait probablement dire que si un langage ne dispose pas de littéraux décimaux, l'utilisation d'une constante serait plus efficace que la conversion d'un littéral int en décimal. Tous les langages .NET prennent en charge le type de données System.Decimal, qui fait partie du CLR.

2 votes

Oui, Niki, c'est ce que je voulais dire. Vous pouvez bien sûr utiliser System.Decimal dans tous les langages .NET, mais certains le supportent mieux (comme C# qui a un mot clé décimal et des littéraux décimaux) et d'autres moins. Désolé, l'anglais n'est pas ma langue maternelle...

-1voto

Guffa Points 308133

Parce qu'un Decimal est assez grande et ces valeurs sont couramment utilisées.

Chaque fois que vous utilisez une de ces propriétés, le code ne doit pas contenir une valeur littérale de 16 octets (ou une valeur entière de quatre octets et un appel à une routine de conversion).

-1voto

Orion Edwards Points 54939

Mon opinion c'est qu'ils sont là pour aider à éviter les chiffres magiques.

Les nombres magiques sont en fait partout dans votre code où vous avez un nombre arbitraire qui flotte. Par exemple :

int i = 32;

C'est problématique dans le sens où personne ne peut dire por qué i est réglé sur 32, ou ce que 32 signifie, ou si cela devrait être 32 du tout. C'est magique et mystérieux.

Dans le même ordre d'idées, je vois souvent du code qui fait ceci

int i = 0;
int z = -1;

Pourquoi sont-elles définies sur 0 et -1 ? Est-ce une simple coïncidence ? Ont-ils une signification ? Qui sait ?

Alors que Decimal.One , Decimal.Zero etc. ne vous disent pas ce que les valeurs signifient dans le contexte de votre application (peut-être que zéro signifie "manquant", etc.). fait vous indiquent que la valeur a été délibérément fixée, et qu'elle a probablement une certaine signification.

Même si ce n'est pas parfait, c'est bien mieux que de ne rien dire du tout :-)

Note C'est no pour l'optimisation. Observez ce code C# :

public static Decimal d = 0M;
public static Decimal dZero = Decimal.Zero;

En regardant le bytecode généré à l'aide d'ildasm, les deux options donnent comme résultat identique MSIL. System.Decimal est un type de valeur, donc Decimal.Zero n'est pas plus "optimale" que l'utilisation d'une valeur littérale.

1 votes

Votre argument me fait mal à la tête. Ce sont des nombres, ils ne deviennent magiques que lorsque vous commencez à leur donner une signification aléatoire, comme -1 signifie faire la vaisselle et 1 signifie faire des gâteaux. Decimal.One est tout aussi magique que 1 mais sans doute plus difficile à lire (mais peut-être plus optimal).

0 votes

Ce que je voulais dire, c'est que si quelqu'un tape Decimal.Zero, il est plus probable qu'il l'ait fait délibérément parce que le zéro a une signification - plutôt que de le mettre arbitrairement à 0.

0 votes

Je ne suis pas d'accord pour dire qu'attribuer une valeur à 0 est arbitraire. Cela a du sens pour les énumérations avec des constantes symboliques mappées à des nombres, mais pour des nombres mappés à des nombres, cela semble assez insensé. Parfois, 0 est vraiment... zéro. D'un autre côté, les unités seraient une construction intéressante. 1km != 1.

-6voto

metro Points 329

Ces 3 valeurs arghhhh ! !!

Je pense qu'ils ont peut-être quelque chose à voir avec ce que j'appelle les 1 de queue

disons que vous avez cette formule :

(x)1.116666 + (y) = (z)2.00000

mais x , z sont arrondis à 0.11 y 2.00 et on vous demande de calculer (y).

alors vous pouvez penser y = 2.00 - 1.11 . En fait, y est égal à 0.88 mais vous obtiendrez 0.89 . (il existe un 0.01 en différence).

Selon la valeur réelle de x et y, les résultats varient de -0.01 a +0.01 et, dans certains cas, lorsqu'il s'agit de traiter un grand nombre de ces 1 de fin, et pour faciliter les choses, vous pouvez vérifier si la valeur de fin est égale à Decimal.MinusOne / 100 , Decimal.One / 100 o Decimal.Zero / 100 pour les réparer.

C'est ainsi que je les ai utilisés.

5 votes

De quoi parlez-vous ? Tu fais de mauvais calculs avec des valeurs inexactes et tu utilises l'opérateur de division pour obtenir ton epsilon ? Qu'est-ce qui vous fait croire que le résultat sera toujours différent d'exactement 0,01, et non (par exemple) de 0,005 ? Si ces valeurs représentent de l'argent, j'aurais peur de faire affaire avec votre application.

0 votes

:) Je ne calcule pas un résultat final, je dois donner la valeur de (y) pour le format arrondi. comment allez-vous faire ?

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