Existe-t-il un équivalent C du type décimal de C #?

Oct 17 2020

En relation avec: Convertir Decimal en Double

Maintenant, je suis arrivé à de nombreuses questions relatives au type à virgule flottante de C # appelé decimalet j'ai vu ses différences avec les deux floatet double, ce qui m'a fait réfléchir s'il y avait un équivalent à ce type en C.

Dans la question spécifiée, j'ai une réponse que je souhaite convertir en C:

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;

Bien sûr, le seul changement est la deuxième ligne, mais avec le decimaltype, je veux savoir que c'est l'équivalent en C.

Question: Quel est l'équivalent C des C # decimal?

Réponses

6 S.S.Anne Oct 19 2020 at 22:08

C2X normalisera la virgule flottante décimale comme suit :_DecimalNhttp://www.open-std.org/jtc1/sc22/wg14/www/docs/n2573.pdf

De plus, GCC implémente la virgule flottante décimale comme extension; il prend actuellement en charge les flottants décimaux 32 bits, 64 bits et 128 bits.

4 ViniciusAlmeida Oct 22 2020 at 01:47

Edit: une grande partie de ce que j'ai dit ci-dessous est tout simplement faux , comme l'a souligné phuclv dans les commentaires. Même dans ce cas, je pense qu'il y a des informations précieuses à gagner en lisant cette réponse, je vais donc la laisser sans modification ci-dessous.

Donc en bref: oui, il existe un support pour les Decimalvaleurs à virgule flottante et l'arithmétique dans le langage C standard. Consultez le commentaire de phuclv et la réponse de SS Anne .


Dans le langage de programmation C, comme d'autres l'ont commenté, il n'y a pas de Decimaltype , ni de types implémentés comme celui-ci. Le type le plus simple qui s'en rapproche serait double, qui est implémenté, le plus souvent, en tant que type à virgule flottante 64 bits conforme à la norme IEEE-754. Il contient un signe de 1 bit, un exposant de 11 bits et une mantisse / fraction de 52 bits. L'image suivante le représente assez bien (de wikipedia ):

Vous avez donc le format suivant:

Une explication plus détaillée peut être lue ici , mais vous pouvez voir que la partie exposant est une puissance de deux, ce qui signifie qu'il y aura des imprécisions lors de la division et de la multiplication par dix. Une explication simple est que la division par tout ce qui n'est pas une puissance de deux est sûre de répéter indéfiniment les chiffres en base 2. Exemple: 1/10 = 0,1 (en base 10) = 0,00011001100110011 ... (en base 2). Et, comme les ordinateurs ne peuvent pas stocker un nombre illimité de zéros, vos opérations devront être tronquées / approximées.

Dans le cas des C # Decimal, à partir de la documentation :

La représentation binaire d'un nombre décimal se compose d'un signe de 1 bit, d'un nombre entier de 96 bits et d'un facteur d'échelle utilisé pour diviser le nombre entier et spécifier quelle partie de celui-ci est une fraction décimale.

Cette dernière partie est importante, car au lieu d'être une multiplication par une puissance de deux, c'est une division par une puissance de dix . Vous avez donc le format suivant:

Ce qui, comme vous pouvez le voir clairement, est une implémentation complètement différente d'en haut!

Par exemple, si vous souhaitez diviser par une puissance de 10, vous pouvez le faire exactement , car cela implique simplement d'augmenter la partie exposant (N). Vous devez être conscient de la limitation des nombres qui peuvent être représentés par Decimal, cependant, qui est tout au plus un maigre 7,922816251426434e + 28, alors qu'il doublepeut aller jusqu'à 1,79769e + 308.

Étant donné qu'il n'y a pas (encore) d'équivalents dans C to Decimal, vous vous demandez peut-être "qu'est-ce que je fais?". En fait ça dépend. Tout d'abord, est-il vraiment important pour vous d'utiliser un Decimaltype? Vous ne pouvez pas utiliser un double? Pour répondre à cette question, il est utile de savoir pourquoi ce type a été créé en premier lieu. Encore une fois, à partir de la documentation de Microsoft :

Le type de valeur décimal convient aux calculs financiers qui nécessitent un grand nombre de chiffres intégraux et fractionnaires significatifs et aucune erreur d'arrondi

Et, juste à la phrase suivante:

Le type Decimal n'élimine pas la nécessité d'arrondir. Au contraire, il minimise les erreurs dues à l'arrondissement

Vous ne devriez donc pas penser Decimalà une "précision infinie", mais plutôt à un type plus approprié pour les calculs qui doivent généralement être effectués dans le système décimal (comme les calculs financiers, comme indiqué ci-dessus).

Si vous voulez toujours un Decimaltype de données en C, vous devrez travailler au développement d'une bibliothèque pour prendre en charge l'addition, la soustraction, la multiplication, etc. --- Parce que C ne prend pas en charge la surcharge d'opérateurs. De plus, il n'aurait toujours pas de support matériel (par exemple à partir du jeu d'instructions x64), donc toutes vos opérations seraient plus lentes que celles de double, par exemple. Enfin, si vous voulez toujours quelque chose qui prend Decimalen charge a dans d'autres langages (dans votre dernière question), vous pouvez consulter Decimal TR en C ++ .

1 SimonMourier Oct 23 2020 at 08:42

Comme d'autres l'ont souligné, il n'y a rien dans les standards C tels que le décimal de .NET, mais, si vous travaillez sur Windows et que vous disposez du SDK Windows, il est défini:

Structure DECIMAL (wtypes.h)

Représente un type de données décimal qui fournit un signe et une échelle pour un nombre (comme dans les coordonnées).

Les variables décimales sont stockées sous forme d'entiers non signés de 96 bits (12 octets) mis à l'échelle par une puissance variable de 10. La puissance du facteur de mise à l'échelle 10 spécifie le nombre de chiffres à droite de la virgule décimale et va de 0 à 28.

typedef struct tagDEC {
  USHORT wReserved;
  union {
    struct {
      BYTE scale;
      BYTE sign;
    } DUMMYSTRUCTNAME;
    USHORT signscale;
  } DUMMYUNIONNAME;
  ULONG  Hi32;
  union {
    struct {
      ULONG Lo32;
      ULONG Mid32;
    } DUMMYSTRUCTNAME2;
    ULONGLONG Lo64;
  } DUMMYUNIONNAME2;
} DECIMAL;

DECIMAL est utilisé pour représenter une valeur numérique exacte avec une précision fixe et une échelle fixe .

L'origine de ce type est l'automatisation COM / OLE de Windows (introduite pour VB / VBA / Macros, etc. donc, elle est antérieure à .NET, qui a un très bon support d'automatisation COM), documentée ici officiellement: [MS-OAUT]: OLE Protocole d'automatisation, 2.2.26 DECIMAL

C'est aussi un du type VARIANT (VT_DECIMAL). Dans l'architecture x86, sa taille s'intègre parfaitement dans le VARIANT (16 octets).

ZivojinMilutinovic Oct 24 2020 at 21:55

Le type décimal en C # est utilisé avec une précision de 28 à 29 chiffres et sa taille est de 16 octets.Il n'y a même pas d'équivalent proche en C à C # .En Java, il existe un type de données BigDecimal qui est le plus proche des données décimales C # type.C # decimal vous donne des nombres comme:

+/- someInteger / 10 ^ someExponent

où someInteger est un entier non signé de 96 bits et someExponent est un entier compris entre 0 et 28.

Le BigDecimal de Java est-il le type de données le plus proche correspondant au Decimal de C #?