Types simples (Delphi)

De RAD Studio
Aller à : navigation, rechercher

Remonter à Types de données, variables et constantes - Index

Les types simples, qui comportent les types ordinaux et les types réels, définissent des ensembles ordonnés de valeurs.

Types ordinaux

Les types ordinaux incluent les types entier, caractère, booléen, énuméré et intervalle. Un type ordinal définit un ensemble ordonné de valeurs dans lequel chaque valeur, sauf la première, a un prédécesseur unique et chaque valeur, sauf la dernière, a un successeur unique. En outre, chaque valeur a un rang qui détermine l'ordre du type. Dans la plupart des cas, si une valeur a le rang n, son prédécesseur a le rang n-1 et son successeur a le rang n+1.

Pour les types entiers, le rang d'une valeur est la valeur elle-même. Les types sous-intervalle conservent les rangs de leurs types de base. Pour les autres types ordinaux, la première valeur a par défaut le rang 0, la suivante a le rang 1, et ainsi de suite. La déclaration d'un type énuméré peut explicitement redéfinir cette valeur par défaut.

Plusieurs fonctions prédéfinies opèrent sur les valeurs ordinales et les identificateurs de type. Les plus importantes sont résumées ci-dessous.

Fonction Paramètre Valeur de retour Remarques

Ord

Expression ordinale

Rang de la valeur de l'expression

Ne prend pas d'arguments Int64.

Pred

Expression ordinale

Prédécesseur de la valeur de l'expression

     Succ

Expression ordinale

Successeur de la valeur de l'expression

     High

Identificateur de type ordinal ou variable de type ordinal

Plus grande valeur du type

Opère également sur les types chaîne courte et les tableaux.

Low

Identificateur de type ordinal ou variable de type ordinal

Plus petite valeur du type

Opère également sur les types chaîne courte et les tableaux.


Par exemple, High(Byte) renvoie 255 car la plus grande valeur du type Byte est 255, et Succ(2) renvoie 3 car 3 est le successeur de 2.

Les procédures standard Inc et Dec incrémentent et décrémentent la valeur d'une variable ordinale. Par exemple, Inc(I) est équivalent à I := Succ(I) et, si I est une variable entière, c'est également équivalent à I := I + 1.

Types entiers

Un type entier représente un sous-ensemble des nombres intégraux.

Les types entiers peuvent être dépendants de la plate-forme et indépendants de la plate-forme.

Types entiers dépendants de la plate-forme

Les types entiers dépendants de la plate-forme sont transformés pour s'ajuster à la taille en bits de la plate-forme du compilateur en cours. Les types entiers dépendants de la plate-forme sont NativeInt, NativeUInt, LongInt et LongWord. L'utilisation de ces types est souhaitable dans la mesure du possible, puisqu'ils donnent de meilleures performances pour le système d'exploitation et la CPU sous-jacente. Le tableau suivant illustre leurs intervalles et les formats de stockage pour le compilateur Delphi.

Types entiers dépendants de la plate-forme

Type Intervalle Format Alias

NativeInt

-2147483648..2147483647
-2^63..2^63-1

Signé sur 32 bits sur les plates-formes 32 bits ou
Signé sur 64 bits sur les plates-formes 64 bits

Integer
Int64

NativeUInt

0..4294967295
0..2^64-1

Non signé sur 32 bits sur les plates-formes 32 bits ou
Non signé sur 64 bits sur les plates-formes 64 bits

Cardinal
UInt64

LongInt

-2147483648..2147483647
-263..263-1

Plates-formes Windows 32 bits et 64 bits
Plates-formes iOS 64 bits

Integer
Int64

LongWord

0..4294967295
0..264-1

Plates-formes Windows 32 bits et 64 bits
Plates-formes iOS 64 bits

Cardinal
UInt64

Remarque : Les plates-formes 32 bits incluent Windows 32 bits, OSX32, iOS 32 bits et Android.

Types entiers indépendants de la plate-forme

Les types entiers indépendants de la plate-forme ont toujours la même taille, quelle que soit la plate-forme utilisée. Les types entiers indépendants de la plate-forme incluent ShortInt, SmallInt, LongInt, Integer, Int64, Byte, Word, LongWord, Cardinal et UInt64.

Types entiers indépendants de la plate-forme

Type Intervalle Format Alias

ShortInt

-128..127

Signé sur 8 bits

Int8

SmallInt

-32768..32767

Signé sur 16 bits

Int16

FixedInt

-2147483648..2147483647

Signé sur 32 bits

Int32

Integer

-2147483648..2147483647

Signé sur 32 bits

Int32

Int64

-2^63..2^63-1

Signé sur 64 bits

     Byte

0..255

Non signé sur 8 bits

UInt8

Word

0..65535

Non signé sur 16 bits

UInt16

FixedUInt

0..4294967295

Non signé sur 32 bits

UInt32

Cardinal

0..4294967295

Non signé sur 32 bits

UInt32

UInt64

0..2^64-1

Non signé sur 64 bits


En général, les opérations arithmétiques sur les entiers renvoient une valeur de type Integer, qui est équivalente au type LongInt sur 32 bits. Les opérations ne renvoient une valeur de type Int64 que si elles portent sur un ou plusieurs opérandes Int64. Par conséquent, le code suivant produit des résultats incorrects :

var
I: Integer;
J: Int64;
... 
I := High(Integer);
J := I + 1;

Pour obtenir une valeur de retour Int64 dans cette situation, transtypez I en Int64 :

...
J := Int64(I) + 1;

Pour de plus amples informations, voir Opérateurs arithmétiques.

Remarque : Certaines routines standard qui attendent des arguments entiers tronquent les valeurs Int64 à 32 bits. Toutefois, les routines High, Low, Succ, Pred, Inc, Dec, IntToStr et IntToHex supportent complètement les arguments Int64. De même, les fonctions Round, Trunc, StrToInt64 et StrToInt64Def renvoient des valeurs Int64. Quelques routines n'acceptent pas les valeurs Int64.

Quand vous incrémentez la dernière valeur ou décrémentez la première valeur d'un type entier, le résultat boucle sur le début ou la fin de l'intervalle. Par exemple, le type ShortInt a l'étendue -128..127 ; donc après l'exécution du code suivant :

var
I: Shortint;
...
I := High(Shortint);
I := I + 1;

la valeur de I est -128. Si la vérification des limites de compilation est activée, ce code génère néanmoins une erreur d'exécution.

Types caractères

Les types caractères sont Char, AnsiChar, WideChar, UCS2Char et UCS4Char :

  • Char dans l'implémentation en cours est équivalent à WideChar, puisque le type de chaîne par défaut est maintenant UnicodeString. Puisque l'implémentation de Char peut changer dans les futures releases, il est judicieux d'utiliser la fonction standard SizeOf plutôt qu'une constante codée en dur lors de l'écriture de programmes qui doivent gérer des caractères de tailles différentes.
  • Les valeurs AnsiChar sont des caractères sur un octet (8 bits) ordonnés selon le jeu de caractères local éventuellement multi-octets.
  • Les caractères WideChar utilisent plus d'un octet pour représenter chaque caractère. Dans les implémentations en cours, les valeurs WideChar sont des caractères sur un mot (16 bits) ordonnés selon le jeu de caractères Unicode (ils pourraient être plus longs dans de futures implémentations). Les 256 premiers caractères Unicode correspondent aux caractères ANSI.
  • UCS2Char est un alias pour WideChar.
  • UCS4Char est utilisé pour fonctionner avec des caractères Unicode sur 4 octets.

Une constante chaîne de longueur 1, comme 'A', peut désigner une valeur caractère. La fonction prédéfinie Chr renvoie la valeur caractère pour tout entier de l'étendue de WideChar ; par exemple Chr(65) renvoie la lettre A.

Les valeurs AnsiChar et WideChar, comme les entiers, bouclent quand elles sont décrémentées ou incrémentées au-delà du début ou de la fin de leur étendue (à moins que la vérification des limites ne soit activée). Ainsi, une fois le code suivant exécuté :

var Letter: AnsiChar;
I: Integer;
begin
  Letter := High(Letter);
  for I := 1 to 66 do Inc(Letter);
end;

Letter a la valeur A (ASCII 65).

Remarque : Le type AnsiChar n'est pas pris en charge par les compilateurs mobiles Delphi, mais il est utilisé par les compilateurs de bureau Delphi. Pour davantage d'informations, voir Migration du code Delphi en mobile depuis le bureau.

Types booléens

Les 4 types booléens prédéfinis sont Boolean, ByteBool, WordBool et LongBool. Boolean est le type de prédilection. Les autres types existent pour fournir la compatibilité avec les bibliothèques des autres langages et systèmes d'exploitation.

Une variable Boolean occupe un octet de mémoire, une variable ByteBool occupe également un octet, une variable WordBool occupe 2 octets (un mot), et une variable LongBool occupe 4 octets (2 mots).

Les valeurs booléennes sont désignées par les constantes prédéfinies True et False. Les relations suivantes s'appliquent :

Boolean ByteBool, WordBool, LongBool

False < True

False <> True

Ord(False) = 0

Ord(False) = 0

Ord(True) = 1

Ord(True) <> 0

Succ(False) = True

Succ(False) = True

Pred(True) = False

Pred(False) = True


Une valeur de type ByteBool, LongBool ou WordBool est considérée comme True quand son rang est non nul. Si une telle valeur apparaît dans un contexte où un Boolean est attendu, le compilateur convertit automatiquement toute valeur de rang non nul en True.

Les remarques précédentes portent sur le rang des valeurs booléennes, non pas sur les valeurs mêmes. Dans Delphi, les expressions booléennes ne peuvent être comparées avec des entiers ou des réels. Par exemple, si X est une variable entière, l'instruction :

if X then ...;

génère une erreur de compilation. Le transtypage de la variable en un type booléen n'est pas fiable, mais les deux alternatives suivantes fonctionnent.

 if X <> 0 then ...;    { use an expression that returns a Boolean value }
  ...
 var OK: Boolean;       { use a Boolean variable }
   ... 
 if X <> 0 then
   OK := True;
 if OK then ...;

Types énumérés

Un type énuméré définit un ensemble ordonné de valeurs en énumérant simplement les identificateurs désignant ces valeurs. Les valeurs n'ont pas de signification propre. Pour déclarer un type énuméré, utilisez la syntaxe suivante :

 type typeName = (val1, ...,valn)

typeName et chaque val sont des identificateurs valides. Par exemple, la déclaration :

type Suit = (Club, Diamond, Heart, Spade);

définit une suite énumérée appelée Suit dont les valeurs possibles sont Club, Diamond, Heart et Spade, où Ord(Club) renvoie 0, Ord(Diamond) renvoie 1, et ainsi de suite.

Quand vous déclarez un type énuméré, vous déclarez chaque val comme une constante de type typeName. Si les identificateurs val sont utilisés dans un autre but dans la même portée, il y a un conflit de nom. Si, par exemple vous déclarez le type :

type TSound = (Click, Clack, Clock)

Malheureusement, Click est aussi le nom d'une méthode définie pour TControl et tous les objets de la VCL qui en descendent. Donc, si vous écrivez une application et créez un gestionnaire d'événement tel que :

 procedure TForm1.DBGridEnter(Sender: TObject);
  var
     Thing: TSound;
     begin 
       ... 
       Thing := Click;
     end;

vous obtiendrez une erreur de compilation ; le compilateur interprète Click dans la portée de la procédure comme une référence à la méthode Click d'un TForm. Vous pouvez contourner ce problème en qualifiant l'identificateur ; si TSound est déclarée dans MyUnit, vous devez utiliser :

Thing := MyUnit.Click;

Une meilleure solution consiste néanmoins à choisir des noms de constantes qui ne rentrent pas en conflit avec d'autres identificateurs. Exemples :

type
  TSound = (tsClick, tsClack, tsClock);
  TMyColor = (mcRed, mcBlue, mcGreen, mcYellow, mcOrange);
  Answer = (ansYes, ansNo, ansMaybe)

Vous pouvez utiliser directement la construction (val1, ..., valn) dans les déclarations des variables, comme nom de type :

var MyCard: (Club, Diamond, Heart, Spade);

Mais si vous déclarez MyCard de cette manière, vous ne pouvez pas déclarer une autre variable dans la même portée en utilisant ces identificateurs de constantes. Ainsi :

 var Card1: (Club, Diamond, Heart, Spade);
 var Card2: (Club, Diamond, Heart, Spade);

génère une erreur de compilation. Mais :

var Card1, Card2: (Club, Diamond, Heart, Spade);

se compile sans problème, tout comme :

type 
  Suit = (Club, Diamond, Heart, Spade); 
  var 
    Card1: Suit;
    Card2: Suit;

Types énumérés avec les rangs explicitement assignés

Par défaut, le rang des valeurs énumérées commence à 0 et suit la séquence dans laquelle leurs identificateurs sont listés dans la déclaration de type. Vous pouvez redéfinir cela en assignant explicitement les rangs de certaines ou de toutes les valeurs de la déclaration. Pour assigner un rang à une valeur, faites suivre son identificateur de = constantExpression, où constantExpression est une expression constante dont le résultat est un entier. Par exemple :

type Size = (Small = 5, Medium = 10, Large = Small + Medium);

définit un type appelé Size dont les valeurs possibles sont Small, Medium et Large, où Ord(Small) renvoie 5, Ord(Medium) renvoie 10 et Ord(Large) renvoie 15.

Un type énuméré est en effet un intervalle dont les valeurs inférieure et supérieure correspondent aux rangs inférieur et supérieur des constantes de la déclaration. Dans l'exemple précédent, le type Size a 11 valeurs possibles dont le rang va de 5 à 15. (Ici, le type array[Size] of Char représente un tableau de 11 caractères.) Seules trois de ces valeurs ont un nom, mais les autres sont accessibles par le biais de transtypages et de routines comme Pred, Succ, Inc et Dec. Dans l'exemple suivant, des valeurs "anonymes" dans l'étendue de Size sont assignées à la variable X.

var 
  X: Size; 
  X := Small;   // Ord(X) = 5 
  X := Size(6); // Ord(X) = 6 
  Inc(X);       // Ord(X) = 7

Toute valeur à laquelle un rang n'a pas été explicitement assigné a pour rang un de plus que celui de la valeur précédente de la liste. Si aucun rang n'est assigné à la première valeur, son rang est 0. Ici, étant donné la déclaration :

type SomeEnum = (e1, e2, e3 = 1);

SomeEnum a seulement deux valeurs possibles : Ord(e1) renvoie 0, Ord(e2) renvoie 1, et Ord(e3) renvoie également 1 ; comme e2 et e3 ont le même rang, ils représentent la même valeur.

Les constantes énumérées sans valeur spécifique ont des informations RTTI :

type SomeEnum = (e1, e2, e3);

alors que les constantes énumérées avec une valeur spécifique (comme dans l'exemple ci-dessous) n'en ont pas :

type SomeEnum = (e1 = 1, e2 = 2, e3 = 3);

Enumérations de portée

Vous pouvez utiliser les énumérations de portée dans le code Delphi si vous activez la directive {$SCOPEDENUMS ON} du compilateur.

La directive {$SCOPEDENUMS ON ou OFF} du compilateur active ou désactive l'utilisation des énumérations de portée dans le code Delphi. {$SCOPEDENUMS ON} définit que les énumérations sont des énumérations de portée. {$SCOPEDENUMS ON} affecte des déclarations de types énumération jusqu'à la directive {$SCOPEDENUMS OFF} la plus proche. Les identificateurs de l'énumération introduite dans les types énumération déclarés après la directive {$SCOPEDENUMS ON} ne sont pas ajoutés à la portée globale. Pour utiliser un identificateur d'énumération de portée, vous devez le qualifier avec le nom du type énumération introduisant cet identificateur.

Par exemple, définissons l'unité suivante dans le fichier Unit1.pas

unit Unit1;
interface
// {$SCOPEDENUMS ON} // clear comment from this directive
 type
   TMyEnum = (First, Second, Third);
implementation
 
end.

et le programme suivant en utilisant cette unité

program Project1;
{$APPTYPE CONSOLE}

uses
  SysUtils, Unit1 in 'Unit1.pas';
 
var
  // First: Integer;  // clear comment from this variable
  Value: TMyEnum;
begin
  try
    Value := First;   
//  Value := TMyEnum.First; 
//  Value := unit1.First; 
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

Nous pouvons maintenant étudier les effets de la directive {$SCOPEDENUMS} du compilateur sur les portées dans lesquelles les identificateurs First, Second et Third, définis dans l'énumération TMyEnum, sont visibles.

Commencez par exécuter (F9) ce code. Le code s'exécute correctement. Cela signifie que l'identificateur First, utilisé dans la variable

Value := First;

est l'identificateur de porté globale introduit dans le type énumération

TMyEnum = (First, Second, Third);

A présent, effacez le commentaire de la directive

{$SCOPEDENUMS ON}

du compilateur dans l'unité unit1. Cette directive applique l'énumération TMyEnum à générer. Lancez la commande Exécuter. L'erreur E2003 Identificateur non déclaré : 'First' est générée sur la ligne

Value := First;

Elle vous informe que la directive {$SCOPEDENUMS ON} du compilateur empêche l'ajout de l'identificateur First, introduit dans l'énumération TMyEnum de portée, à la portée globale.

Pour utiliser les identificateurs introduits dans les énumérations de portée, préfixez une référence à un élément d'énumération avec son nom de type. Par exemple, effacez le commentaire dans la seconde version

Value := TMyEnum.First;

de la variable Value (et commentez la première version de Value). Lancez la commande Exécuter. Le programme s'exécute correctement. Cela signifie que l'identificateur First est connu dans la portée TMyEnum.

Maintenant, commentez la directive

// {$SCOPEDENUMS ON}

du compilateur dans unit1. Puis effacez le commentaire de la déclaration de la variable First

First: Integer; 

et utilisez à nouveau la variable

Value := First;

A présent, le code dans program Project1 ressemble à :

var
  First: Integer;   
  Value: TMyEnum;
begin
  try
    Value := First;

Lancez la commande Exécuter. La ligne

 First: Integer;   

provoque l'erreur E2010 Types incompatibles - 'TMyEnum' et 'Integer'. Cela signifie que le conflit de nommage se produit entre l'identificateur First de portée globale introduit dans l'énumération TMyEnum et la variable First. Vous pouvez contourner ce conflit en qualifiant l'identificateur First avec l'unité unit1 dans laquelle il est défini. Pour cela, commentez à nouveau la première version de la variable Value et effacez le commentaire de la troisième :

Value := unit1.First;

Lancez la commande Exécuter. Le programme s'exécute correctement. Cela signifie qu'à présent l'identificateur First peut être qualifié avec la portée d'unité unit1. Voyons ce qui se passe si nous activons à nouveau la directive

{$SCOPEDENUMS ON}

du compilateur dans unit1. L'erreur E2003 Identificateur non déclaré : 'First' est générée sur la ligne

Value := unit1.First;

Cela signifie que {$SCOPEDENUMS ON} empêche l'ajout de l'identificateur First de l'énumération dans la portée unit1. A présent l'identificateur First est ajouté seulement dans la portée TMyEnum de l'énumération. Pour vérifier cela, utilisons à nouveau la version

Value := TMyEnum.First;

de la variable Value. Lancez la commande Exécuter. Le code s'exécute correctement.

Types sous-intervalle

Un type sous-intervalle représente un sous-ensemble de valeurs d'un autre type ordinal (appelé le type de base). Toute construction de la forme Low..High, où Low et High sont des expressions constantes du même type ordinal, Low étant inférieur à High, identifie un type sous-intervalle qui inclut toutes les valeurs comprises entre Low et High. Si par exemple, vous déclarez le type énuméré :

type 
  TColors = (Red, Blue, Green, Yellow, Orange, Purple, White, Black);

vous pouvez définir le type sous-intervalle suivant :

type 
  TMyColors = Green..White;

Ici TMyColors inclut les valeurs Green, Yellow, Orange, Purple et White.

Vous pouvez utiliser des constantes numériques ou des caractères (constantes chaîne de longueur 1) pour définir des types sous-intervalle :

type 
 SomeNumbers = -128..127;
 Caps = 'A'..'Z';

Quand vous utilisez des constantes numérique ou caractère pour définir un sous-intervalle, le type de base est le plus petit type entier ou caractère contenant l'intervalle spécifié.

La construction LowerBound..UpperBound fonctionne directement comme nom de type, vous pouvez donc l'utiliser directement dans des déclarations de variables. Par exemple :

var SomeNum: 1..500;

déclare une variable entière dont la valeur est dans l'intervalle allant de 1 à 500.

Le rang de chaque valeur d'un sous-intervalle est préservé depuis le type de base. (Dans le premier exemple, si Color est une variable contenant la valeur Green, Ord(Color) renvoie 2, que Color soit de type TColors ou TMyColors.) Les valeurs ne bouclent pas au début ou à la fin du sous-intervalle même si le type de base est de type entier ou caractère ; l'incrémentation ou la décrémention au-delà des limites d'un sous-intervalle convertit simplement la valeur dans le type de base. Ainsi, tandis que :

 type Percentile = 0..99;
 var I: Percentile;
   ... 
   I := 100;

produit une erreur, le code suivant :

 ...
 I := 99;
 Inc(I);

assigne la valeur 100 à I (à moins que la vérification des limites de compilation ne soit activée).

L'utilisation d'expressions constantes dans les définitions des sous-intervalles introduit une difficulté syntaxique. Dans toute déclaration de type, quand le premier caractère significatif après = est une parenthèse gauche, le compilateur suppose qu'un type énuméré est défini. Ainsi, le code :

 const X = 50; Y = 10;
 type Scale = (X - Y) * 2..(X + Y) * 2;

produit une erreur. Pour contourner ce problème, il faut réécrire la déclaration de type afin d'éviter la parenthèse de début :

 type Scale = 2 * (X - Y)..(X + Y) * 2;

Types réels

Un type réel définit un ensemble de nombres pouvant être représentés avec la notation à virgule flottante. Le tableau ci-dessous donne les intervalles et les formats de stockage des types réels sur les plates-formes 32 bits et 64 bits.

Types réels

Type Intervalle positif approximatif Chiffres significatifs Taille en octets
Real48 2.9e-39 .. 1.7e+38 11-12 6
Single 1.5e-45 .. 3.4e+38 7-8 4
Double 5.0e-324 .. 1.7e+308 15-16 8
Real 5.0e-324 .. 1.7e+308 15-16 8
Extended
  • Plates-formes 32 bits : 3.4e-4932 .. 1.1e+4932
  • Plates-formes 64 bits : 5.0e-324 .. 1.7e+308
10-20

15-16

10

8

Comp -9223372036854775808.. 9223372036854775807
(-263.. 263-1)
10-20 8
Currency -922337203685477.5808.. 922337203685477.5807
(-(263+1)/10000.. 263/10000)
10-20 8

Les remarques suivantes s'appliquent aux types réels :

  • Real est équivalent à Double, dans l'implémentation en cours.
  • Real48 est conservé pour la compatibilité descendante. Comme son format de stockage n'est pas natif à l'architecture des processeurs Intel, ce type produit des performances plus mauvaises que les autres types à virgule flottante.
Le type Real48 sur 6 octets s'appelait Real dans les versions précédentes de Object Pascal. Si vous recompilez du code utilisant l'ancien type Real sur 6 octets dans Delphi, vous pouvez le changer en Real48. Vous pouvez également utiliser la directive {$REALCOMPATIBILITY ON} du compilateur qui revient à l'interprétation de Real comme un type sur 6 octets.
  • Extended offre une plus grande précision sur les plates-formes 32 bits que les autres types réels.
Sur les plates-formes 64 bits, Extended est l'alias d'un Double ; c'est-à-dire que la taille du type de données Extended est de 8 octets. Vous avez ainsi moins de précision en utilisant un type Extended sur les plates-formes 64 bits que sur les plates-formes 32 bits, où la taille du type Extended est de 10 octets. Par conséquent, si vos applications utilisent le type de données Extended et que vous comptez sur la précision pour les opérations à virgule flottante, cette différence de taille peut affecter vos données. Soyez prudent en utilisant Extended si vous créez des fichiers de données qui doivent être partagés sur plusieurs plates-formes. Pour de plus amples informations, voir Le type de données Extended est de 2 octets plus petit sur les systèmes Windows 64 bits.
  • Le type Comp est un type natif de l'architecture des processeurs Intel et représente un entier sur 64 bits. Il est néanmoins classé parmi les réels car il ne se comporte pas comme un type ordinal. (Par exemple, il n'est pas possible d'incrémenter ou de décrémenter une valeur Comp.) Comp est conservé uniquement pour la compatibilité descendante. Utilisez le type Int64 pour de meilleures performances.
  • Currency est un type de données à virgule fixe qui minimise les erreurs d'arrondi dans les calculs monétaires. Il est stocké dans un entier sur 64 bits, les 4 chiffres les moins significatifs représentant implicitement les positions décimales. Lorsqu'il est combiné à d'autres types réels dans des affectations et des expressions, les valeurs Currency sont automatiquement divisées ou multipliées par 10000.

Voir aussi