FAQ CConsultez toutes les FAQ

Nombre d'auteurs : 27, nombre de questions : 175, dernière mise à jour : 17 décembre 2010  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de www.developpez.com et de l'expérience personnelle des auteurs.

Je tiens à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez devenir rédacteur, lisez ceci .

Sur ce, je vous souhaite une bonne lecture.


SommaireLes types et les variablesLes nombres flottants (3)
précédent sommaire suivant
 

En l'affectant à une variable de type entier.

Code C :
1
2
double f = 10.9; 
int n = f; /* n contient la troncature de f (c'est-a-dire 10) */
L'affectation d'une valeur réelle à un entier pousse cependant la plupart des compilateurs à émettre un avertissement (warning). Pour éviter ces messages, il vaut mieux caster le réel en int puis affecter le résultat à la variable entière.

Mis à jour le 2 mars 2003 Bob

Les fonctions floor() et ceil(), déclarées dans math.h, permettant d'obtenir respectivement l'entier immédiatement inférieur (la « partie entière ») et l'entier immédiatement supérieur. Notez toutefois que ces fonctions retournent des double et non des int. Pour arrondir un nombre à son entier le plus proche, il suffit de lui ajouter 0.5 et de prendre la partie entière du résultat.

Maintenant, pour arrondir un nombre à n décimales après la virgule, on peut utiliser la méthode suivante :

  • multiplier le nombre par 10 à la puissance n
  • arrondir le résultat puis diviser par 10 à la puissance n

La fonction suivante arrondit le nombre passé en argument à n décimales après la virgule.

Code C :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <math.h> 
  
unsigned dix_puissance_n(unsigned n) 
{ 
    unsigned i, res = 1; 
  
    for(i = 0; i < n; i++) 
        res *= 10; 
  
    return res; 
} 
  
double arrondi(const double x, unsigned n) 
{ 
    unsigned N = dix_puissance_n(n); 
    return floor(x * N + 0.5) / N; 
}

Mis à jour le 12 avril 2003 Jean-Marc.Bourguet

L'opérateur == est défini pour les nombres réels cependant, étant donné que cet opérateur ne fait qu'une comparaison bit à bit des valeurs comparées, il ne doit être utilisé que pour ce type de comparaison or ce n'est généralement pas ce que l'on souhaite faire. Pour tester l'égalité de deux réels, il faut calculer leur différence et voir si elle est assez petite (et assez petite est à définir par le programmeur !). En effet, les calculs avec les nombres réels ne se font pas toujours avec une précision infinie. Cela signifie qu'un calcul qui devrait donner pour résultat 0.0 par exemple peut ne pas retourner exactement 0.0 à cause des éventuelles pertes en précision qui ont pu avoir lieu lors des calculs intermédiaires et c'est pourquoi, le programmeur doit toujours lui-même définir une certaine tolérance à l'erreur à chaque calcul utilisant les nombres réels.

La source de ce problème, c'est qu'il existe une infinité de nombres réels et l'ordinateur n'est bien entendu pas capable de pouvoir les représenter tous. En d'autres termes, l'ensemble des nombres représentables par l'ordinateur est discret et fini et non continu. La distance entre deux réels consécutifs de cet ensemble n'est cependant pas forcément constante. Il existe une macro définie dans float.h appelée DBL_EPSILON qui représente la plus petite valeur x de type double tel que 1.0 + x != 1.0. En d'autres termes, DBL_EPSILON est le réel tel que le successeur de 1.0 dans l'ensemble des nombres représentables par le système est 1.0 + DBL_EPSILON.

Donc comment choisir epsilon ? Tout dépend de l'ordre de grandeur des valeurs comparées et de la tolérance à l'erreur que l'on veut avoir. Il n'y a donc rien d'absolu (ou « d'universel ») que l'on peut affirmer sur ce sujet. Si les nombres comparés sont de l'ordre de l'unité (mais pas trop proches de zéro), on peut choisir un epsilon absolu. Si la distance entre les deux nombres (c'est-à-dire |x - y|) est inférieure à epsilon, alors on doit les considérer comme « égaux ». Dans les autres cas, il faut généralement être beaucoup moins tolérant (comparaison de nombres proches de zéro par exemple) ou beaucoup plus tolérant (comparaison de grands nombres). Il faut par exemple considérer un epsilon e tel que x est égal à y (on suppose que |x| < |y|) s'il existe un réel k tel que |k| < e et y = x + k.x. e est appelée erreur relative maximale autorisée. k est l'erreur relative qu'il y a entre x et y. L'avantage de cette méthode, c'est qu'elle choisit automatiquement le epsilon absolu qui va le mieux en fonction des nombres comparés. C'est donc cette méthode qui est utilisée dans la plupart des applications.

Voici une fonction qui permet de comparer deux réels avec deux epsilons spécifiés : le premier absolu et le deuxième relatif. Choisir 0 comme epsilon absolu pour l'ignorer (c'est-à-dire, comparer directement en utilisant le epsilon relatif).

Code c :
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
/* Fonction dbl_cmp : Compare deux réels x et y */ 
/* Retourne :                                   */ 
/*    -1 si x < y                               */ 
/*     0 si x = y                               */ 
/*     1 si x > y                               */ 
  
int dbl_cmp(double x, double y, double eps_a, double eps_r) 
{ 
    double a, b; 
    int ret; 
  
    /* On tente tout d'abord une comparaison bit a bit. */ 
  
    if (x < y) 
    { 
        a = x; 
        b = y; 
        ret = -1; 
    } 
    else if (x > y) 
    { 
        a = y; 
        b = x; 
        ret = 1; 
    } 
    else 
        ret = 0; 
  
    /* Si x != y, on tente alors une comparaison avec tolérance à l'erreur. */ 
  
    if (ret != 0) 
    { 
        /* Si eps_a != 0, l'utiliser. */ 
  
        if (b - a < eps_a) 
        { 
            ret = 0; 
        } 
  
        if (ret != 0) 
        { 
            /* Si on a encore ret != 0 (i.e. x != y), utiliser eps_r. */ 
  
            if ((b - a) / a < eps_r) 
                ret = 0; 
        } 
    } 
  
    return ret; 
}

Mis à jour le 23 mars 2009 Melem

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2014 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
 
 
 
Partenaires

PlanetHoster
Ikoula