Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server
MS SQL-Server Forum Microsoft SQL-Server. Avant de poster -> FAQ SQL-Server, Tutoriels SQL-Server
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 19/05/2011, 23h18   #1
Membre Expert
 
Inscription : octobre 2007
Messages : 3 947
Détails du profil
Informations forums :
Inscription : octobre 2007
Messages : 3 947
Points : 1 905
Points : 1 905
Par défaut arrondis float inaccepables

Bonjour

Je suis confronté a un problème d'arrondi
Je ne sais pas si le probleme vient du type de données ou de conversion

Dans une table j'ai deux float
223,92
97,76

Je lis ces float en Csharp / ADO

Je retrouve bien deux float Csharp : 223,92 et 97,76
Je resauve ces données dans une autre table et voici ce que j'obtiens !

Est-il possible d'eviter cela ?

QT TpUnite PrixNet
223,919998168945 M2 9,76000022888184


Merci de votre aide
__________________
« Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)
olibara est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/05/2011, 07h09   #2
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
Bonjour,

Je soupçonne fort une différence de mantisse entre le type float de C# et le type float de SQL Server.

Regardez la table suivante : je crois qu'il faudrait que vous utilisiez un Double en C# ...

Notons au passage que le type de données float de SQL Server n'est pas un type de données précis.
Il vaut mieux donc utiliser le type numeric ou decimal.

En revanche je ne comprend pas d'où vient la différence entre 97,76 et 9,76000022888184 (divisé par un peu plus 10 ?)

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/05/2011, 09h48   #3
Membre Expert
 
Inscription : octobre 2007
Messages : 3 947
Détails du profil
Informations forums :
Inscription : octobre 2007
Messages : 3 947
Points : 1 905
Points : 1 905
Citation:
Envoyé par elsuket Voir le message
En revanche je ne comprend pas d'où vient la différence entre 97,76 et 9,76000022888184 (divisé par un peu plus 10 ?)
@++
Sans doute une difference d'exposant sur mon clavier

Merci Elsuket et merci pour ce tableau,

Je vais travailler en double dans C#
__________________
« Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)
olibara est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/05/2011, 12h22   #4
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
A votre place :

- Je changerai le type des deux colonnes vers numeric ou decimal : une quantité et un prix sont des valeurs précises

- Je changerai le type de données C# en conséquence pour utiliser Decimal, comme indiqué par la table

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/05/2011, 16h56   #5
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 954
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 954
Points : 17 774
Points : 17 774
Citation:
Envoyé par elsuket Voir le message
Notons au passage que le type de données float de SQL Server n'est pas un type de données précis.
Mais c'est normalisé !
Citation:
Il vaut mieux donc utiliser le type numeric ou decimal.

En revanche je ne comprend pas d'où vient la différence entre 97,76 et 9,76000022888184 (divisé par un peu plus 10 ?))
Problème récurent dux aux IHM (notamment VB) et à divers paramétrages (style régionale.....).

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/05/2011, 16h57   #6
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 954
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 954
Points : 17 774
Points : 17 774
Citation:
Envoyé par elsuket Voir le message
- Je changerai le type des deux colonnes vers numeric ou decimal : une quantité et un prix sont des valeurs précises
Pour un prix oui, mais pas pour une quantité.
Par exemple si la "quantité" est au litre ou au poids et que vous achetez de l'or ou du safran, les décimales feront toutes la différence !!!!!

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/05/2011, 23h05   #7
Membre éprouvé
 
Homme Hamid MIRA
Ingénieur développement logiciels
Inscription : septembre 2003
Messages : 177
Détails du profil
Informations personnelles :
Nom : Homme Hamid MIRA
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2003
Messages : 177
Points : 413
Points : 413
Citation:
Envoyé par elsuket Voir le message
Bonjour,
[...]
Notons au passage que le type de données float de SQL Server n'est pas un type de données précis.
Il vaut mieux donc utiliser le type numeric ou decimal.
[...]
C'est une idée fausse assez répondue de dire que le type float n'est pas précis. Tout dépend de l'utilisation que l'on fait. Ci-dessous un exemple où le type float s'avère plus précis !

Code :
1
2
3
4
5
6
7
8
9
DECLARE @float1 float, 
        @float2 float, 
        @float3 float,
        @float4 float;
 
SET @float1 = 145;
SET @float2 = 0.07;
SET @float3 = @float1/@float2;
SELECT @float3 / @float1 * @float2  AS "Doit être égale à 1";
Code :
1
2
3
Résultat : 
Doit être égale à 1
1

Code :
1
2
3
4
5
6
7
8
9
DECLARE @decimal1  decimal(12,4),
        @decimal2  decimal(12,4),
        @decimal3  decimal(12,4),
        @decimal4  decimal(12,4); 
 
SET @decimal1 = 145;
SET @decimal2 = 0.07;
SET @decimal3 = @decimal1/@decimal2;
SELECT @decimal3 / @decimal1 * @decimal2  AS "Doit être égale à 1";
Code :
1
2
3
Résulat 
Doit être égale à 1
1.00000001379310345
Je ne veux surtout pas dire qu'il faut utiliser le type float au lieu de décimal, ni l’inverse. Chacun des 2 types a son utilité. le type float peut être un bon choix pour les calculs scientifiques puisqu'il permet des mesures aussi proche de la réalité (plus précis !). le type decimal peut être approprié pour les chiffres ayant un nombre fixe de décimal tels que les montants exprimés en devise.

Autre chose, transformer un type float en décimal est légitime et cela peut être un bon choix en rapport avec l’utilisation que vous en faites, mais attention, ce n'est pas transparent pour votre application. Je veux dire que ce n'est pas anodin et que cela peut générer des erreurs et des régressions dans votre application.

Exemple :

Code :
1
2
3
4
5
DECLARE @decimal1 decimal(8,4), @decimal2 decimal(8,4), @decimal3 decimal(8,4);
SET @decimal1 = 47;
SET @decimal2 = 0.002;
SET @decimal3 =  @decimal1 / @decimal2;
SELECT @decimal3 / @decimal1 * @decimal2 AS "Doit être égale à 1";
Résulat :
Msg*8115, Niveau*16, État*8, Ligne*4
Une erreur de dépassement arithmétique s'est produite lors de la conversion de numeric en type de données numeric.


alors qu'en utilisant le type float le programme ne générait aucune erreur !

A+
hmira est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/05/2011, 08h57   #8
Membre Expert
 
Inscription : octobre 2007
Messages : 3 947
Détails du profil
Informations forums :
Inscription : octobre 2007
Messages : 3 947
Points : 1 905
Points : 1 905
Bon !

Et bien merci pour ces enseignement !

je vais donc maintenant me battre pour essayer de trouver la meilleure combinaison possible afin de stocker en DB des quantité a 4 décimale et des valeurs a deux decimales et manipuler celles ci correctement en C#

Ca ne semble hélas pas trivial mais d'apres ce que je comprends le bon choix serait peut etre de travailler en Decimal des deux cotés (Sql Server et C#)

Personnelement je n'ai jamais travaillé en Décimal qui me semblait un type batard par raport au double ou au float !
__________________
« Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)
olibara est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/05/2011, 07h40   #9
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
Pour ma part je n'utilise ni float (aucun calcul scientifique dans l'application sur laquelle je travaille) et surtout jamais le pseudo-type money, qui lui par contre produit des erreurs de calcul bien connues.

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/05/2011, 14h20   #10
Membre Expert
 
Inscription : octobre 2007
Messages : 3 947
Détails du profil
Informations forums :
Inscription : octobre 2007
Messages : 3 947
Points : 1 905
Points : 1 905
Bonjour Elsuket
Effectivement j'avais déja constaté que Money est a proscrire
Par contre quand je suis en C# j'utilise généralement les doubles

Que me conseillerais tu en définitive pour assurer un bon dialogue avec SQL Server ?
decimal partout ?
__________________
« Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)
olibara est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/05/2011, 10h04   #11
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
Désolé de ma réponse très tardive, mais je me dois de revenir là-dessus :

Citation:
Envoyé par hmira
C'est une idée fausse assez répondue de dire que le type float n'est pas précis. Tout dépend de l'utilisation que l'on fait. Ci-dessous un exemple où le type float s'avère plus précis !
D'abord, dans la documentation, float est classé sous les "Valeurs numériques approximatives".
La définition qui en est donnée est la suivante :

Citation:
Types de données approximatives à utiliser avec des données numériques à virgule flottante. Les données à virgule flottante sont approximatives ; il n'est donc pas possible de représenter précisément toutes les valeurs de ce type de données.
Donc ce n'est pas une rumeur ... démonstration (SQL Server 2008):

Code :
1
2
3
DECLARE @f float
SELECT @f = 1111146804871.1111222233334444
SELECT @f
Retourne : 1111146804871.11
Donc on vient de perdre une précision qui peut s'avérer non négligeable dans des calculs, quels qu'ils soient.

Second exemple :

Citation:
DECLARE @big float
, @small float
, @sum1 float
, @sum2 float
, @sum3 float
, @i int

SELECT @big = 12345678901234.50
, @small = 0.01
, @i = 0

SELECT @sum1 = @big
, @sum2 = 0
, @sum3 = 0

WHILE @i < 5
BEGIN
SELECT @sum1 = @sum1 + @small
, @sum2 = @sum2 + @small
, @sum3 = @sum3 + @small

SET @i = @i + 1
END

SELECT @sum2 = @sum2 + @big

SELECT @sum1 AS [@sum1]
, @sum2 AS [@sum2]
, @sum3 AS [@sum3]
Retourne :

Citation:
@sum1 @sum2 @sum3
12345678901234.5 12345678901234.6 0.05
Autrement dit, l'ordre de calcul influe sur le résultat.
Or, l'addition est commutative, donc mathématiquement, ce résultat est faux.

Ensuite, votre démonstration est fausse sur ce point :

Code :
SET @decimal3 = @decimal1/@decimal2;
si je fais un SELECT @decimal3, j'obtiens 2071.42857142857142857.
En le stockant dans un decimal(12,4) vous perdez de la précision en ne stockant que les 4 premières décimales.
Ce qui explique par la suite que votre résultat soit "faux".

Si je reprends votre exemple en changeant la précision et l'échelle pour "contenir" les calculs :

Code :
1
2
3
4
5
6
7
8
9
10
11
DECLARE @decimal1 decimal(29,17),
        @decimal2 decimal(29,17),
        @decimal3 decimal(29,17),
        @decimal4 decimal(29,17)
 
SET @decimal1 = 145;
SET @decimal2 = 0.07;
 
 
SET @decimal3 = @decimal1/@decimal2;
SELECT @decimal3 / @decimal1 * @decimal2  AS "Doit être égale à 1";
Retourne : 1.000000, ce qui est correct.

Donc encore une fois, le choix du type de données approprié non seulement au stockage de la donnée et aux calculs que l'on peut effectuer sur ces valeurs ne doit jamais être négligé.

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 17/07/2011, 19h01   #12
Membre éprouvé
 
Homme Hamid MIRA
Ingénieur développement logiciels
Inscription : septembre 2003
Messages : 177
Détails du profil
Informations personnelles :
Nom : Homme Hamid MIRA
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2003
Messages : 177
Points : 413
Points : 413
Merci beaucoup Elsuket pour ce retour d'information, et tes investigations sur le sujet. Les exemples que tu donnes ne sont pas dénoués d'intérêts. Ils sont très intéressants.

Le premier exemple peut être effectivement déroutant pour le développeur qui voit ainsi s'évaporer par magie plusieurs chiffre de précision !

Pour revenir à mon exemple. Il ne s'agit pas d'une erreur de ma part. J'avais bien vu qu'en augmentant la précision on allait retomber sur ses pieds. J'ai gardé exprès cet exemple pour montrer un cas d'utilisation où le float donne un résultat plus précis (ou plus juste) que le type décimal. En effet, on ne peut pas toujours ajuster la précision au cas par cas ! Il y a des situations où l'utilisation du type Float s'avère incontournable, notamment lorsqu'on ne connait pas à l'avance l'ordre de grandeur. (exemple une table représentant les distances séparant des « entités » (nanoparticules, atomes, villes, étoiles, etc..). dans ce cas les distances peuvent varier de l’infiniment petit à l’infiniment grand. et dans ce contexte, l'utilisation du type décimal serait impossible et le type Float serait le plus approprié.

J'ai réétudié la question et fini par établi mes propres conclusions sur le sujet, conclusions que je vous livre :

- Le type decimal un bon choix, et est approprié pour représenter les montants dont on connait l'ordre de grandeur et la précision souhaitée.

- Les types de données float (ou real) présentant un caractère approximatif, ne doivent pas être utilisées lorsqu'un comportement numérique exact est requis, comme dans les applications financières, les opérations comprenant des arrondis ou les vérifications d'égalité. Il faut utiliser, en lieu et place, en fonction de la nature de l'information, les types de données comme integer, decimal, money ou smallmoney, etc.. (extrait de http://msdn.microsoft.com/fr-fr/library/ms187912.aspx)

- Le type float doit être réservé au calcul scientifique. Le type Float est approprié lorsque veut représenter un très large éventail de valeur allant de l’infiniment petit à l’infiniment grand, c.à.d pour représenter les nombre réels au sens mathématique du terme.

- Le type Float SQL Server s'approche de la norme IEEE 754 (mais ne respecte pas complétement la norme IEEE 754). En effet, ni la valeur NaN (Not-a-Number,), ni l'infinie ne peuvent être représentés. Toute tentative de conversion d'une chaîne non numérique en type numérique et de division par zéro entraîne une erreur. Beaucoup de développeurs n'avaient pas d'autres choix, et ont fini par représenter les NaN et l'infini par des valeur NULL.
(Pour plus de détails, voir : http://msdn.microsoft.com/fr-fr/library/ms172002.aspx)

- Il faut évitez d'utiliser les colonnes de type float (ou real) dans les clause WHERE, plus particulièrement les opérateurs = et <>. L'idéal est de limiter les colonnes float et real aux signes de comparaison > ou <.

A+
hmira est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/07/2011, 14h22   #13
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
Merci pour ces références.

Citation:
(exemple une table représentant les distances séparant des « entités » (nanoparticules, atomes, villes, étoiles, etc..). dans ce cas les distances peuvent varier de l’infiniment petit à l’infiniment grand. et dans ce contexte, l'utilisation du type décimal serait impossible et le type Float serait le plus approprié.
Héhé je ne suis pas d'accord, parce que dans ce cas-là il s'agit d'une erreur de modélisation, et vous les dites vous même !
Vous auriez du avoir une entité nanoparticule, une autre atome, une autre ville, un autre étoile, etc ...
Vous pouvez dans ce cas utiliser la spécialisation, c'est à dire créer une entité dont tous les attributs sont communs à chacune de celles qui constituent votre liste, et dans chaque entité, ajouter seulement les attributs qui sont particuliers à celles-ci.
Chaque entité référence l'entité "mère"

D'autre part je pense que la mantisse de 38 chiffres significatifs est suffisante de très petites comme de très grandes distances.

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/07/2011, 19h52   #14
Membre éprouvé
 
Homme Hamid MIRA
Ingénieur développement logiciels
Inscription : septembre 2003
Messages : 177
Détails du profil
Informations personnelles :
Nom : Homme Hamid MIRA
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2003
Messages : 177
Points : 413
Points : 413
Ce n'est pas un problème de conception ! C'est un problème de « domaine », au sens relationnel du terme ; c.à.d. l’ensemble dans lequel les données d'un attribut (ie une colonne d'une relation) prennent valeur.

Le domaine Float, est défini par intention :
Float (n) ensemble des nombres en virgule flottante codé sur 32 bits (soit 4 octets) si n <= 24 ou sur 64 bit (8 octets) si 25<=n<=53
Comparé au domaine Decimal défini également par intention :
decimal[ (p[ ,s] )] ensemble des numériques ayant une précision et une échelle fixes. Où p représente la précision et s représente l'échelle
Code :
1
2
3
4
5
Précision  Taille de stockage (octets)
19	   5 octets
10-19   9 octets
20-28  13 octets 
29-38  17 octets
Quand je parlais de l'infiniment petit et de l'infiniment grand, je voulais mettre l'accent sur le fait que le domaine float (ou le type float) permet de représenter des valeurs allant de l'infiniment petit (jusqu'à la limite +/- 2.23E-308), à l'infiniment grand (jusqu'à la limite de +/- 1.79E+308)

Tu ne pourras jamais représenter, par exemple, le nombre 1.79E+308 en utilisant le type décimal !
Code :
1
2
3
4
5
SELECT CAST(1.79E+308 AS DECIMAL(38,0) ) -- résultat Une erreur de dépassement arithmétique
SELECT CAST(1.79E+308 AS DECIMAL(38,1) ) -- résultat Une erreur de dépassement arithmétique
SELECT CAST(1.79E+308 AS DECIMAL(38,2) ) -- résultat Une erreur de dépassement arithmétique
-- .... 
SELECT CAST(1.79E+308 AS DECIMAL(38,38) ) -- résultat Une erreur de dépassement arithmétique
De même (même raisonnement), tu ne pourras jamais représenter l'infiniment petit, par exemple, le nombre 2.23E-308 en utilisant le type décimal !

Donc on ne peut pas toujours remplacer le type Float par le type Decimal.

Autres remarques : Nous avons tendance à considérer le type Float comme un ensemble purement mathématique, le confondant souvent avec l'ensemble R ( ensemble des nombre réels en mathématique), ce qui est une erreur.

L'ensemble R, au sens mathématique du terme, est un espace topologique au sens limite et continuité.

Or le type Float, par définition représenté physiquement, en mémoire, en binaire, par des 0 et 1, au plus sur 8 octets, ne pourra jamais représenter un espace topologique intégrant les notions de limite de continuité. Il ne peut donc s'agir, au mieux, que d'un espace ou d'une topologie discrète où les points sont isolés les uns des autres.

Ci-dessous quelques résultats, qui sur le plan mathématique pur, peuvent apparaître surprenant voire même déroutant !

Code :
1
2
3
4
5
6
7
8
9
10
11
SELECT '(-2.23E-308) < 0' AS Expression,  CASE WHEN (-2.23E-308) < 0 THEN 'Vrai' ELSE 'Faux' END Resultat 
UNION ALL 
SELECT '(-1.115E-308) < 0' AS Expression,  CASE WHEN (-1.115E-308) < 0 THEN 'Vrai' ELSE 'Faux' END Resultat 
UNION ALL 
SELECT '(-1.115E-308) = 0' AS Expression,  CASE WHEN (-1.115E-308) = 0 THEN 'Vrai' ELSE 'Faux' END Resultat 
UNION  ALL 
SELECT '(1.115E-308) > 0' AS Expression,  CASE WHEN (1.115E-308) > 0 THEN 'Vrai' ELSE 'Faux' END Resultat 
UNION ALL 
SELECT '(1.115E-308) = 0' AS Expression,  CASE WHEN (1.115E-308) = 0 THEN 'Vrai' ELSE 'Faux' END Resultat 
UNION ALL 
SELECT '(+2.23E-308) > 0' AS Expression,  CASE WHEN (2.23E-308) > 0 THEN 'Vrai' ELSE 'Faux' END Resultat
Résultat :

Code :
1
2
3
4
5
6
7
Expression	Resultat
(-2.23E-308) < 0	Vrai    --  OK 
(-1.115E-308) < 0	Faux -- surprenant sur le  plan mathématique !
(-1.115E-308) = 0	Vrai  -- surprenant sur le plan mathématique !
(1.115E-308) > 0	Faux -- surprenant sur le plan mathématique !
(1.115E-308) = 0	Vrai  --  surprenant sur le plan mathématique !
(+2.23E-308) > 0	Vrai  -- OK

De même
Code :
1
2
3
4
5
6
7
8
9
SELECT '(2.23E-308)' AS Expression, 2.23E-308 AS Resultat 
UNION ALL 
SELECT '0 + (2.23E-308)' AS Expression, 0 + 2.23E-308 AS Resultat 
UNION ALL 
SELECT '1 + (2.23E-308)' AS Expression, 1 + 2.23E-308 AS Resultat 
UNION ALL
SELECT '2 + (2.23E-308)' AS Expression, 2 + 2.23E-308 AS Resultat 
UNION ALL
SELECT '3 + (2.23E-308)' AS Expression, 3 + 2.23E-308 AS Resultat
Résultat :
Code :
1
2
3
4
5
6
Expression	Resultat
(2.23E-308)	2,23E-308   -- OK 
0 + (2.23E-308)	2,23E-308   -- OK 
1 + (2.23E-308)	1   -- surprenant sur le  plan mathématique !
2 + (2.23E-308)	2   -- surprenant sur le  plan mathématique !
3 + (2.23E-308)	3   -- surprenant sur le  plan mathématique !
A+
hmira est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 19h54.


 
 
 
 
Partenaires

Hébergement Web