IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Firebird Discussion :

Types Decimal & Numeric !


Sujet :

Firebird

  1. #1
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 778
    Par défaut Types Decimal & Numeric !
    Salut à tous.

    Je suis sous Windows 10 Pro et j'utilise FireBird version 4.0.2.

    Dans la documentation officielle de FireBird, il est dit que "Decimal" et "Numeric" sont synonymes.
    --> Documentation FireBird 4.0.
    Il y a une erreur dans la documentation puisqu'il est dit que le type decimal peut être sur 16 bits.
    C'est faux ! Seul le type Numeric peut être sur 16 bits.

    Dans mon test ci-après, j'ai chercher la limite qui permet de stocker le plus grand nombre soit en decimal soit en numeric.
    J'ai aussi fait varier la mantisse, mais je n'ai pas touché à l'exposant qui dans mon exemple est à 2.
    La mantisse est la plus grande valeur possible avant le changement dans le stockage de la valeur.

    Voici mon test :
    Code firebird : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    CREATE TABLE TEST (val  numeric(4,2));
    INSERT INTO  TEST (val) VALUES (327.67);
    INSERT INTO  TEST (val) VALUES (327.68);
    Statement failed, SQLSTATE = 22003
    arithmetic exception, numeric overflow, or string truncation
    -numeric value is out of range
    After line 2 in file Base.sql
     
    SELECT * FROM TEST;
     
        VAL
    =======
     327.67
     
    COMMIT;
     
    RECREATE TABLE TEST (val  numeric(9,2));
    INSERT   INTO  TEST (val) VALUES (21474836.47);
    INSERT   INTO  TEST (val) VALUES (21474836.48);
    Statement failed, SQLSTATE = 22003
    arithmetic exception, numeric overflow, or string truncation
    -numeric value is out of range
    After line 9 in file Base.sql
     
    SELECT * FROM TEST;
     
             VAL
    ============
     21474836.47
     
    COMMIT;
     
    RECREATE TABLE TEST (val  numeric(18,2));
    INSERT   INTO  TEST (val) VALUES (92233720368547758.07);
    INSERT   INTO  TEST (val) VALUES (92233720368547758.08);
    Statement failed, SQLSTATE = 22003
    arithmetic exception, numeric overflow, or string truncation
    -Integer overflow.  The result of an integer operation caused the most significant bit of the result to carry.
    After line 16 in file Base.sql
     
    SELECT * FROM TEST;
     
                      VAL
    =====================
     92233720368547758.07
     
    COMMIT;
     
    commit;
    RECREATE TABLE TEST (val  numeric(36,2));
    INSERT   INTO  TEST (val) VALUES (1701411834604692317316873037158841057.27);
    INSERT   INTO  TEST (val) VALUES (1701411834604692317316873037158841057.28);
    Statement failed, SQLSTATE = 22003
    arithmetic exception, numeric overflow, or string truncation
    -numeric value is out of range
    After line 24 in file Base.sql
     
    SELECT * FROM TEST;
     
                                              VAL
    =============================================
         1701411834604692317316873037158841057.27
     
    COMMIT;
     
    RECREATE TABLE TEST (val decimal(9,2));
    INSERT   INTO  TEST (val) VALUES (21474836.47);
    INSERT   INTO  TEST (val) VALUES (21474836.48);
    Statement failed, SQLSTATE = 22003
    arithmetic exception, numeric overflow, or string truncation
    -numeric value is out of range
    After line 31 in file Base.sql
     
    SELECT * FROM TEST;
     
             VAL
    ============
     21474836.47
     
    COMMIT;
     
    RECREATE TABLE TEST (val decimal(18,2));
    INSERT   INTO  TEST (val) VALUES (92233720368547758.07);
    INSERT   INTO  TEST (val) VALUES (92233720368547758.08);
    Statement failed, SQLSTATE = 22003
    arithmetic exception, numeric overflow, or string truncation
    -Integer overflow.  The result of an integer operation caused the most significant bit of the result to carry.
    After line 38 in file Base.sql
     
    SELECT * FROM TEST;
     
                      VAL
    =====================
     92233720368547758.07
     
    commit;
     
    RECREATE TABLE TEST (val  decimal(36,2));
    INSERT   INTO  TEST (val) VALUES (1701411834604692317316873037158841057.27);
    INSERT   INTO  TEST (val) VALUES (1701411834604692317316873037158841057.28);
    Statement failed, SQLSTATE = 22003
    arithmetic exception, numeric overflow, or string truncation
    -numeric value is out of range
    After line 45 in file Base.sql
     
    SELECT * FROM TEST;
     
                                              VAL
    =============================================
         1701411834604692317316873037158841057.27
     
    exit;
     
    Appuyez sur une touche pour continuer...
    Comme on peut le constater, la première valeur passe tandis que la seconde est rejeté, soit sous "out of range" ou soit sous "overflow".

    Je tiens à mettre au point la méconnaissance que certains ont à ce sujet, de ce que j'ai pu lire dans ce forum.
    Je ne citerai pas les noms, ils se reconnaitrons certainement d'eux même.

    a) le decimal et le numeric sont stockés en entiers binaires ! Il y a le choix entre quatre types :
    --> Smallint : 16 bits
    --> Integer : 32 bits
    --> Bigint : 64 bits
    --> Int128 : 128 bits

    P.S.: Int128 est un nouveau type qui est apparu dans la version FireBird 4.0.

    b) Le premier nombre dans la déclaration du type Decimal ou Numeric se nomme mantisse.
    Ce nombre ne sert pas à limiter le nombre de chiffres à l'affichage, mais à déterminer le type de stockage.

    Le deuxième nombre se nomme l'exposant. Il sert à positionner la virgule fixe dans le nombre stockée.

    Dans le cas de la déclaration "Decimal(36,2)", 36 est la mantisse et 2 est l'exposant.
    Dans le nombre +2127 - 1, j'ai au total 39 chiffres alors que la mantisse indique 36 seulement.
    Le fait de donner 36 comme mantisse, va automatiquement attribuer le type Int128 pour le stockage.
    L'exposant est 2. En lisant la mantisse par la droite, on place la virgule fixe à gauche du deuxième chiffres.

    c) Il ne s'agit pas d'une représentation DCB (decimal codé binaire) comme j'ai pu le lire.
    Pour rappel, en DCB, un chiffre décimal est stocké dans un quartet, c'est-à-dire sur quatre bits.
    Les N chiffres seront stockés sur N * 4 bits. Pour un nombre de 36 chiffres, il faut 36 * 4 = 144 bits soit 18 octets.
    Avec la représentation binaire, il suffit de 16 octets au maximum pour stocker nos 36 chiffres décimaux
    De ce fait, on gagne deux octets, ce qui n'est pas négligeable dans une base de données de plusieurs millions de lignes.

    En Cobol, le DCB est utilisé dans le type packed decimal qui utilise la clause COMP-3.
    A ma connaissance, il n'y a pas de représentation DCB dans FireBird.

    d) Pour les limites, nous trouvons :
    --> 2 15 = 32 768
    --> 2 31 = 2 147 483 648
    --> 2 63 = 9 223 372 036 854 775 808
    --> 2127 = 170 141 183 460 469 231 731 687 303 715 884 105 728

    Pourquoi cette limite ? Parce que l'on stocke des nombres signés.

    e) Voici le résumé du type Numeric :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    +---------+--------------------+-------------------+------------------+-------------------+
    |  Type   |    Range 1 to 4    |   Range 5 to 9    |  Range 10 to 18  |  Range 19 to 36   |
    +---------+--------------------+-------------------+------------------+-------------------+
    | Numeric | Smallint (16 bits) | Integer (32 bits) | Bigint (64 bits) | int128 (128 bits) |
    +---------+--------------------+-------------------+------------------+-------------------+
    f) Et voici le résumé du type Decimal :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    +---------+-------------------+------------------+-------------------+
    |  Type   |   Range 1 to 9    |  Range 10 to 18  |  Range 19 to 36   |
    +---------+-------------------+------------------+-------------------+
    | Decimal | Integer (32 bits) | Bigint (64 bits) | int128 (128 bits) |
    +---------+-------------------+------------------+-------------------+
    e) Après quelques recherches, il s'agit d'une retro compatibilité avec d'anciennes version d'InterBase, v.5 et inférieures.
    Pour le dialect=1, le stockage d'un nombre décimal fixe supérieur à 9 chiffres se faisaient dans du flottant.
    Je suppose que par flottant, il s'agit de float ou de double.
    Pour le dialect=3, cela se fait maintenant dans du fixe. D'après mes tests, il s'agit bien d'entiers binaires.

    f) Il n'y a pas de problèmes d'arrondis car c'est du binaire et non du float ou double.
    Le flottant est réservé aux calculs scientifiques et non au financier.

    Cordialement.
    Artemus24.
    @+

  2. #2
    Membre très actif Avatar de TryExceptEnd
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2006
    Messages
    501
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2006
    Messages : 501
    Par défaut
    Voici une page ou vous trouverez plus d'infos sur les types DECIMAL et NUMERIC de Firebird.

  3. #3
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 778
    Par défaut
    Salut TryExceptEnd.nai

    Je connaissais déjà "ce lien" dont je me suis inspiré.
    A vrai dire, c'est juste une petite étude sur le stockage et les différences entre ces deux types.

    Cordialement.
    Artemus24.
    @+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Type de donnée Numeric/Decimal
    Par awa123 dans le forum Développement
    Réponses: 2
    Dernier message: 29/11/2020, 23h16
  2. Réponses: 2
    Dernier message: 03/01/2012, 12h09
  3. Type de données decimal et numeric
    Par charlie_p07 dans le forum PostgreSQL
    Réponses: 0
    Dernier message: 21/08/2008, 15h13
  4. type DECIMAL et NUMERIC
    Par KRis dans le forum Débuter
    Réponses: 1
    Dernier message: 11/03/2006, 18h52
  5. [C#] Type decimal
    Par Emilio04 dans le forum Windows Forms
    Réponses: 15
    Dernier message: 31/05/2005, 13h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo