OVH Cloud OVH Cloud

problème de flottant

19 réponses
Avatar
none
Je dois travailler avec des flottants pour tracer l'axe d'un repère.
J'ai une routine qui renvoie un pixel en fonction de coordonnées
flottantes (des double).
Maintenant, je dois dessiner un tiret de, disons -1.0 jusqu'à 1.0 tous
les 0.1, donc -1.0, -0.9, ..., 0.0, ..., 1.0

Apparemment, partir de -1.0 et ajouter 0.1 à chaque pas, ça ne
fonctionne visiblement pas. Pour le tiret du milieu, quand je compare ma
valeur à 0.0, ça me renvoie faux :/ Alors que pourtant, je n'ai fait
qu'incrémenter ma valeur de 0.1.
Je pense que c'est un problème récurrent mais j'ai vraiment du mal à
comprendre.
Comment faire proprement pour avoir -1.0, -0.9, etc .. ?

10 réponses

1 2
Avatar
Jean-Marc Bourguet
none <""(none)"@(none)"> writes:

Comment faire proprement pour avoir -1.0, -0.9, etc .. ?


Ne pas utiliser des flottants mais une representation
rationnelle.

Les flottants sont généralement binaires et ne peuvent
representer que des valeurs de la forme m * 2^e ou m et e
sont des entiers. 0.1 n'est pas de cette forme.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Cyrille
Je dois travailler avec des flottants pour tracer l'axe d'un repère.
J'ai une routine qui renvoie un pixel en fonction de coordonnées
flottantes (des double).
Maintenant, je dois dessiner un tiret de, disons -1.0 jusqu'à 1.0 tous
les 0.1, donc -1.0, -0.9, ..., 0.0, ..., 1.0

Apparemment, partir de -1.0 et ajouter 0.1 à chaque pas, ça ne
fonctionne visiblement pas. Pour le tiret du milieu, quand je compare ma
valeur à 0.0, ça me renvoie faux :/ Alors que pourtant, je n'ai fait
qu'incrémenter ma valeur de 0.1.
Je pense que c'est un problème récurrent mais j'ai vraiment du mal à
comprendre.


Toute représentation classique des flottants entraîne des imprécisions.
Quand on additionne des flottants, les imprécisions s'additionnent
également. Après avoir ajouté dix fois 0.1 à -1., tu n'as plus vraiment
0. et c'est normal (mais normalement tu dois avoir quelque chose de très
proche, surtout que tu utilises des double).

Comment faire proprement pour avoir -1.0, -0.9, etc .. ?


// de -1 à 1 par pas de 0.1
for ( int i = -10; i <= 10; i++ )
{
double d = i * 0.1;
// dessiner ce qui correspond à d...
}

L'idée étant de calculer le plus souvent possible avec des entiers, dont
la précision est parfaite, et de passer aux flottants seulement quand
c'est nécessaire. Quand c'est un problème simple de discrétisation comme
ici c'est facile.

Sinon, quand tu compares des flottants, tu peux intégrer une certaine
marge d'erreur. Ainsi tu remplaces
x == y
par
std::abs( x - y ) < epsilon

Avec epsilon une constante que tu as défini à l'avance.

Si ça ne te convient toujours pas, cherche sur Google
"arbitrary-precision float", mais c'est vraiment pour des besoins exigeants.

--
If you want to get anything done in this country you've go to complain
till you're blue in the mouth.

Avatar
Sylvain
none none wrote on 19/03/2006 18:46:
Je dois travailler avec des flottants pour tracer l'axe d'un repère.
J'ai une routine qui renvoie un pixel en fonction de coordonnées
flottantes (des double).
Maintenant, je dois dessiner un tiret de, disons -1.0 jusqu'à 1.0 tous
les 0.1, donc -1.0, -0.9, ..., 0.0, ..., 1.0

Apparemment, partir de -1.0 et ajouter 0.1 à chaque pas, ça ne
fonctionne visiblement pas. Pour le tiret du milieu, quand je compare ma
valeur à 0.0, ça me renvoie faux :/ Alors que pourtant, je n'ai fait
qu'incrémenter ma valeur de 0.1.
Je pense que c'est un problème récurrent mais j'ai vraiment du mal à
comprendre.
Comment faire proprement pour avoir -1.0, -0.9, etc .. ?


un flottant est nécessairement une valeur définie + ou - sa précision,
et cette précision dépend de la taille alloué au type; historiquement le
type float a la taille des registres du CPU/CoPro, le type double le
double; sur ces n bits de stockage sont codés le signe, l'exposant et la
mantisse (la valeur décimale compris entre 0 et 0.99999999..).

chaque opération flottante génère une incertitude relative sur le
résultat (tel qu'on nous l'apprenait en TP de chimie par exemple); donc
tous tests stricts est voué à l'échec et doit plutôt être codé en
comparant l'écart entre la valeur courante et la valeur supposé d'une
part et la précision du type utilisé d'autre part.

concrétement:
ne pas coder if (f == 1.0) {}
mais if (fabs(f - 1.0) < 1e-8) {}

ce type de codage est indispensable lors que vous n'avez pas d'autre
choix que d'utiliser des flottants (et que des flottants); partout ou
cela n'est pas indispensable on réalisera les opérations en entiers et
on convertit (ou seulement exprime) en flottants au dernier moment.

dans votre cas, vous devriez coder:
for (tick = -10; tick <= 10; ++tick){
// calcul des coord. en entiers (les pixels sont des entiers)
// évaluation d'un libellé comme "tick / 10.0"
}

Sylvain.

Avatar
Arnaud Meurgues
none none wrote:

Apparemment, partir de -1.0 et ajouter 0.1 à chaque pas, ça ne
fonctionne visiblement pas. Pour le tiret du milieu, quand je compare ma
valeur à 0.0, ça me renvoie faux :/ Alors que pourtant, je n'ai fait
qu'incrémenter ma valeur de 0.1.


Benvenue dans le monde des flottants.

En informatique, la représentation des nombre rationnels (et
irrationnels) n'est pas exacte. Certaines valeurs ne sont simplement pas
représentable.

Pour simplifier, supposons qu'un nombre flottant entre 0 et 1 (interval
[0,1[) soit représenté sur 3 bits représentant les puissances négatives
de 2.

Ainsi :

000 = 0
001 = 0*2^(-1) + 0*2^(-2) + 1*2^(-3) = 0*0,5 + 0*0,25 + 1*0,125 = 0,125
010 = 0,25
011 = 0,375
100 = 0,5
101 = 0,625
110 = 0,75
111 = 0,875

Avec une telle représentation, si l'on écrit
float x = 0.5
on a bien une représentation exacte.
Mais si l'on écrit
float x = 0.1
la valeur représentée sera en fait 0,125 (ou 0, selon la manière dont
est converti un nombre non représentable en nombre représentable).

De la même manière, les additions entre flottants seront empruntes de la
même inexactitude.

Ainsi, si vous décrémentez de 0,5 jusqu'à 0 par pas de 0,1, vous risquez
(dans cet exemple) d'arriver à 0 en 4 étapes car les pas seraient en
fait de 0,125.

L'on peut aussi, lorsque la précision supérieur au pas (prenez un pas de
0,3, par exemple) "rater" le 0 et n'avoir donc jamais exactement le 0.

Travailler sur des flottants est un exercice extrêmement délicat en
informatique, et il vaut mieux s'en abstenir si l'on n'a pas une
conscience aigüe de tous ces problèmes (et en avoir conscience ne suffit
d'ailleurs pas).

Dans votre cas, il serait plus prudent, par exemple, de tout multiplier
par 10 et de travailler avec des entiers.

Comment faire proprement pour avoir -1.0, -0.9, etc .. ?


Avec des flottant, on ne peut pas...

--
Arnaud

Avatar
none
Comment faire proprement pour avoir -1.0, -0.9, etc .. ?


Avec des flottant, on ne peut pas...



Merci à tous pour ces réponses rapides. Je vais travailler le plus
possible avec des entiers.


Avatar
kanze
Sylvain wrote:
none none wrote on 19/03/2006 18:46:
Je dois travailler avec des flottants pour tracer l'axe d'un
repère. J'ai une routine qui renvoie un pixel en fonction de
coordonnées flottantes (des double).
Maintenant, je dois dessiner un tiret de, disons -1.0
jusqu'à 1.0 tous les 0.1, donc -1.0, -0.9, ..., 0.0, ...,
1.0

Apparemment, partir de -1.0 et ajouter 0.1 à chaque pas, ça
ne fonctionne visiblement pas. Pour le tiret du milieu,
quand je compare ma valeur à 0.0, ça me renvoie faux :/
Alors que pourtant, je n'ai fait qu'incrémenter ma valeur de
0.1.
Je pense que c'est un problème récurrent mais j'ai vraiment
du mal à comprendre.

Comment faire proprement pour avoir -1.0, -0.9, etc .. ?


un flottant est nécessairement une valeur définie + ou - sa
précision,


Strictement parlant... Un flottant a une valeur précise ; il n'y
a pas de + ou -. Pour des raisons évidentes (représentation
finie), les flottants ne peuvent pas représenter tous les réels
(ni toutes les rationnelles) ; malheureusement pour none none,
0.1 est une des valeurs qu'ils ne peuvent pas représenter. Ce
qui fait qu'il n'ajoute pas 0.1 à chaque passage dans la boucle,
mais quelque chose de proche.

et cette précision dépend de la taille alloué au type;
historiquement le type float a la taille des registres du
CPU/CoPro, le type double le double; sur ces n bits de
stockage sont codés le signe, l'exposant et la mantisse (la
valeur décimale compris entre 0 et 0.99999999..).


Ça dépend des formats, mais en IEEE (le format le plus répandu
aujourd'hui), la valeur décimale de la mantisse s'étend de 0.5 à
1.0-epsilon (ou epsilon est 2^-53, je crois). Il y a aussi des
valeurs spéciales, identifiées par une valeur spéciale dans
l'exposant -- 0.0 est sans doute celle qu'on rencontre la plus
souvent.

chaque opération flottante génère une incertitude relative sur
le résultat (tel qu'on nous l'apprenait en TP de chimie par
exemple);


Là aussi, ça dépend du point de vue. La valeur du résultat est
bien définie. Seulement, dans certains cas, elle sera différente
de celle du résultat de l'opération sur les réels. Mais
attention : dans son cas, ça ne serait pas souvent le cas. Et
statistiquement, souvent, ces différences s'anullera. Son
véritable problème, c'est que la valeur qu'il ajoute n'est pas
ce qu'il veut.

donc tous tests stricts est voué à l'échec et doit plutôt être
codé en comparant l'écart entre la valeur courante et la
valeur supposé d'une part et la précision du type utilisé
d'autre part.


Ça dépend de l'application ; souvent, les valeurs en entrée sont
déjà des approximations, et c'est tout à fait normal de prendre
en compte des epsilons quand on cherche une valeur précises --
en fait, ce qu'on veut, au niveau de l'application, c'est déjà
x+/-epsilon (avec un epsilon qui dépend de l'application).

Mais ce n'est pas une règle générale ; ça dépend de
l'application. Et il faut bien ne pas oublier que si on définit
un isEqual() approximatif, alors isEqual(a,b) && isEqual(b,c)
n'implique plut isEqual(a,c) -- ce qui peut faire échouer
certaines algorithmes.

Il y a pire, évidemment, et certains algorithmes, pour certaines
valeurs (qui n'apparaîtront pas dans vos tests, évidemment)
peuvent ne pas converger avec les opérations sur des flottants,
alors qu'ils convergeront bien avec les mêmes opérations sur des
réels.

La question est assez complexe et ne se prete pas à une réponse
simple dans le news -- le mieux, c'est de googler pour « what
every computer scientist should know about floating point
arithmetic », et lire l'article (de David Goldberg) avec
attention. (C'est disponible à beaucoup d'endroits sur la
toile.)

concrétement:
ne pas coder if (f == 1.0) {}
mais if (fabs(f - 1.0) < 1e-8) {}


Si tu sais que dans ton application, la précision des valeurs
est de l'ordre 1e-8. Dans les rares cas où je me sers des
flottants, je m'arrange pour que les valeurs soient toujours
exactes. En revanche, dans une application où je traiterais des
valeurs lues des instruments de mésure électronique, la
précision serait plutôt de l'ordre 1e-2 ou 1e-3 -- les
instruments ne peuvent pas me donner de plus, de toute façon.

C'est le genre de règle naïve qui donne l'air de marcher,
parfois, mais donne aussi des résultats trompeurs dans d'autres
cas.

ce type de codage est indispensable lors que vous n'avez pas
d'autre choix que d'utiliser des flottants (et que des
flottants); partout ou cela n'est pas indispensable on
réalisera les opérations en entiers et on convertit (ou
seulement exprime) en flottants au dernier moment.


Ça, en revanche, c'est un conseil excellent. Moins on fait avec
les flottants, moins on risque de se faire avoir (et moins
l'analyse de la correction de ce qu'on a fait est simple).

dans votre cas, vous devriez coder:
for (tick = -10; tick <= 10; ++tick){
// calcul des coord. en entiers (les pixels sont des entiers)
// évaluation d'un libellé comme "tick / 10.0"
}


C'est certainement la solution dans son cas. Au moins qu'il
n'affiche 17 décimaux ou plus, il verra les valeurs auxquelles
il s'attend.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Sylvain
kanze wrote on 20/03/2006 11:41:

1- tu as le droit de quoter correctement (et donc ne pas laisser des
blocs entiers sans aucun rapport avec ce que tu développes)

2- puisque apparemment ce que tu aimes développer le plus est l'art de
la contradiction (ni systématiquement intéressante, ni spécialement en
charte), je me sens obligé d'indiquer que ce "bizutage" me laisse de glace.

un flottant est nécessairement une valeur définie + ou - sa
précision,


Strictement parlant... Un flottant a une valeur précise ; il n'y
a pas de + ou -. Pour des raisons évidentes (représentation
finie), les flottants ne peuvent pas représenter tous les réels
(ni toutes les rationnelles)


donc "strictement parlant", je te laisserais maintenant monologuer ce
type de platitude.

0.1 est une des valeurs qu'ils ne peuvent pas représenter.


et t'as décréter ça tout seul sans même connaître la précision de son
type double !! ben tu vois un Cray tout bête se représente parfaitement 0.1

qui fait qu'il n'ajoute pas 0.1 à chaque passage dans la boucle,
mais quelque chose de proche.


tu expliques ça à qui ???????? 4 personnes l'ont déjà dit.

Ça dépend des formats, mais en IEEE (le format le plus répandu
aujourd'hui), la valeur décimale de la mantisse s'étend de 0.5 à
1.0-epsilon (ou epsilon est 2^-53, je crois).


la valeur absolue de la mantisse est toujours comprise entre 1 et la
base de dénombrement (le premier bit étant caché car toujours
prédictible, cette mantisse se ramène en base 10 à une quasi partie
fractionnaire pure (un nombre décimale sans partie entière)

tout ceci étant hors chartre, google IEEE.

Il y a aussi des valeurs spéciales, identifiées par une valeur
spéciale dans l'exposant -- 0.0 est sans doute celle qu'on
rencontre la plus souvent.


de l'exposant *et* de la mantisse.

soit il y a le nombre zero (E = 0; F = 0; S = 1)

tu as juste oublié:
-0 (E = 0; F = 0; S = 1)
-Infinity
Infinity
NaN

Là aussi, ça dépend du point de vue. La valeur du résultat est
bien définie.


on va dire ça; tabl[4325] est "indéfini" mais savoir comment le dernier
bit d'un flottant est arrondi par tous les unités flottantes de tous les
fondeurs est "définie" .. "selon le point de vue de James".

Seulement, dans certains cas, elle sera différente
de celle du résultat de l'opération sur les réels. Mais


c'est quoi "réels", c'est pas dans IEEE 754 ni dans IEEE 854.

attention : dans son cas, ça ne serait pas souvent le cas.


c'est cela, "pas souvent" j'vous dis, et même, à vue de nez, pas toujours.

Et statistiquement, souvent, ces différences s'anullera.


grotesque.

Son véritable problème, c'est que la valeur qu'il ajoute n'est
pas ce qu'il veut.


12ième porte ouverte, merci quand même.

Ça dépend de l'application ; souvent, les valeurs en entrée sont
déjà des approximations, et c'est tout à fait normal de prendre
en compte des epsilons quand on cherche une valeur précises --
en fait, ce qu'on veut, au niveau de l'application, c'est déjà
x+/-epsilon (avec un epsilon qui dépend de l'application).


ça a un rapport avec la question, le fil, la chartre ???
ou c'est juste une envolée de plus ?

Mais ce n'est pas une règle générale ; ça dépend de
l'application. Et il faut bien ne pas oublier que si on définit
un isEqual() approximatif, alors isEqual(a,b) && isEqual(b,c)
n'implique plut isEqual(a,c) -- ce qui peut faire échouer
certaines algorithmes.


oui, seulement si tu ne sais pas coder ton isEqual.

Il y a pire, évidemment, et certains algorithmes, pour certaines
valeurs (qui n'apparaîtront pas dans vos tests, évidemment)
peuvent ne pas converger avec les opérations sur des flottants,
alors qu'ils convergeront bien avec les mêmes opérations sur des
réels.


si "réel" voulait signifier "précision arbitraire" (via une librarie
es-spéciale et non une simple unité de calcul flottant) c'est faux
également.

concrétement:
ne pas coder if (f == 1.0) {}
mais if (fabs(f - 1.0) < 1e-8) {}


Si tu sais que dans ton application, la précision des valeurs
est de l'ordre 1e-8.


?!?? non, si tu sais que tu utilises des float (32bits), on utilisera
1e-12 avec des doubles et 1e-14 avec des long doubles.

Dans les rares cas où je me sers des flottants,
je m'arrange pour que les valeurs soient toujours
exactes.


c'est pas du n'importe quoi là ??, tu as répété après tout le monde que
tous les nombres flottants ne pouvaient pas avoir une représentation
exacte de leur valeur, mais toi, abracadabra, tu t'"arranges" avec eux
et hop "c'est exact"; tiens codes donc exactement 7/5

En revanche, dans une application où je traiterais des
valeurs lues des instruments de mésure électronique, la
précision serait plutôt de l'ordre 1e-2 ou 1e-3 -- les
instruments ne peuvent pas me donner de plus, de toute façon.


si, si, c'est vraiment du n'importe quoi. (pousse la porte d'un labo de
physique au moins une fois, tu verras c'est intéressant).

C'est le genre de règle naïve qui donne l'air de marcher,
parfois, mais donne aussi des résultats trompeurs dans d'autres
cas.


[disait Confusius]

Ça, en revanche, c'est un conseil excellent. [...]


?!? te sens pas non plus obliger de distribuer tes bons points.

C'est certainement la solution dans son cas. Au moins qu'il
n'affiche 17 décimaux ou plus, il verra les valeurs auxquelles
il s'attend.


ok, on t'expliquera un jour comment utiliser printf.

Sylvain.


Avatar
Benoit SIBAUD
(ni toutes les rationnelles) ; malheureusement pour none none,
0.1 est une des valeurs qu'ils ne peuvent pas représenter. Ce
qui fait qu'il n'ajoute pas 0.1 à chaque passage dans la boucle,
mais quelque chose de proche.


Codage en binaire (IEEE float 32 bits, double 64 bits, long double 80
bits), prenons le cas des float par exemple :

- 1.0 = (-1)^0 * 2^(127-127)(1.00000000000000000000000)
- 0.1 ~ (-1)^0 * 2^(123-127)(1.10011001100110011001101...)
- 0.9 ~ (-1)^0 * 2^(126-127)(1.11001100110011001100110...)

--
Benoît Sibaud

Avatar
Arnaud Meurgues
Sylvain wrote:

2- puisque apparemment ce que tu aimes développer le plus est l'art de
la contradiction (ni systématiquement intéressante, ni spécialement en
charte), je me sens obligé d'indiquer que ce "bizutage" me laisse de glace.


Je doute qu'il y ait quelque forme que ce soit de « bizutage ». Mais une
chose est sûre : votre ton à vous est extrèmement désagréable dans la
plupart de vos messages.

0.1 est une des valeurs qu'ils ne peuvent pas représenter.
et t'as décréter ça tout seul sans même connaître la précision de son

type double !! ben tu vois un Cray tout bête se représente parfaitement 0.1


« un Cray tout bête », c'est déjà une expression étrange.

Par curiosité, quelle genre de représentation binaire des flottants
utilise ce Cray tout bête pour représenter 0.1 de manière exacte ?

tout ceci étant hors chartre, google IEEE.


Ce n'est pas plus hors charte que vos réponses dans le fil « pb
iwebbrowser2 ». Mais si ça vous amuse de développer l'incohérence en
plus du mépris...

Il y a aussi des valeurs spéciales, identifiées par une valeur
spéciale dans l'exposant -- 0.0 est sans doute celle qu'on rencontre
la plus souvent.
de l'exposant *et* de la mantisse.



Il n'a pas dit le contraire.

soit il y a le nombre zero (E = 0; F = 0; S = 1)

tu as juste oublié:
-0 (E = 0; F = 0; S = 1)
-Infinity
Infinity
NaN


Il dit que 0.0 est celle qu'on rencontre le plus souvent. Il n'a pas
fait un inventaire. bon, c'est sûr, il faut savoir lire pour s'en
apercevoir, ce que rage et mépris ne rendent pas facile.

Là aussi, ça dépend du point de vue. La valeur du résultat est
bien définie.
on va dire ça; tabl[4325] est "indéfini" mais savoir comment le dernier

bit d'un flottant est arrondi par tous les unités flottantes de tous les
fondeurs est "définie" .. "selon le point de vue de James".


Ne pourrait-ce pas être indiqué par numeric_limits<float>::round_style
(tiens, ça c'est en charte) ?

Du coup, ça n'est indéterminé que si numeric_limits<float>::round_style
renvoie round_indeterminate.

Mais ce n'est pas une règle générale ; ça dépend de
l'application. Et il faut bien ne pas oublier que si on définit
un isEqual() approximatif, alors isEqual(a,b) && isEqual(b,c)
n'implique plut isEqual(a,c) -- ce qui peut faire échouer
certaines algorithmes.
oui, seulement si tu ne sais pas coder ton isEqual.



Comment peut-on coder un isEqual approximatif (différent du =, donc) et
transitif ?

Il y a pire, évidemment, et certains algorithmes, pour certaines
valeurs (qui n'apparaîtront pas dans vos tests, évidemment)
peuvent ne pas converger avec les opérations sur des flottants,
alors qu'ils convergeront bien avec les mêmes opérations sur des
réels.
si "réel" voulait signifier "précision arbitraire" (via une librarie

es-spéciale et non une simple unité de calcul flottant) c'est faux
également.


Je pense qu'ici, réels signifie réels, mathématiquement parlant.

Selon vous, une suite qui converge avec des réels converge
obligatoirement avec des flottants ?

concrétement:
ne pas coder if (f == 1.0) {}
mais if (fabs(f - 1.0) < 1e-8) {}
Si tu sais que dans ton application, la précision des valeurs

est de l'ordre 1e-8.
?!?? non, si tu sais que tu utilises des float (32bits), on utilisera

1e-12 avec des doubles et 1e-14 avec des long doubles.


Et avec des floats ?

Dans les rares cas où je me sers des flottants, je m'arrange pour que
les valeurs soient toujours
exactes.



c'est pas du n'importe quoi là ??, tu as répété après tout le monde que
tous les nombres flottants ne pouvaient pas avoir une représentation
exacte de leur valeur, mais toi, abracadabra, tu t'"arranges" avec eux
et hop "c'est exact"; tiens codes donc exactement 7/5


Je suppose qu'il ne vous est pas venu à l'esprit qu'il pouvait
s'arranger pour n'avoir à utilier que des nombres représentables.

En tout cas, merci pour votre contribution aussi riche et aimable. C'est
un bonheur à voir.
--
Arnaud



Avatar
Yoxoman

2- puisque apparemment ce que tu aimes développer le plus est l'art de
la contradiction (ni systématiquement intéressante, ni spécialement en
charte), je me sens obligé d'indiquer que ce "bizutage" me laisse de glace.


Ce qu'écrit James m'interesse. D'ailleurs, si le message t'était
uniquement destiné, je pense qu'il t'aurait plutôt envoyé un mail.

Qu'est-ce qui te dérange dans le fait qu'une personne approfondisse ou
remette en cause ce que tu dis ? Si tu as des problèmes à ce niveau,
trouve un autre groupe. Ici, c'est hors charte.

--
"Yo!"
Martin Heidegger (trad. Terrence Malick)

1 2