Floating point [Résolu]

ethan_decoster 38 Messages postés mardi 31 janvier 2006Date d'inscription 4 avril 2008 Dernière intervention - 7 août 2006 à 18:25 - Dernière réponse : twh19 5 Messages postés mercredi 4 août 2004Date d'inscription 5 janvier 2009 Dernière intervention
- 17 oct. 2007 à 18:30
Dans une base de donnée utilisée pour un de mes programmes, j'ai des données qui ont comme type de champs la valeur reel simple. La base de donnée communique avec le programme via Ado. Donc dans la base de donnée j'ai les valeurs 26.3. Mais a l'affichage dans le programme, la valeur de ce champs est de 26.299365489 ce qui en valeur arrondie me donne 26.3.

Mais le hic ce que je me sert de cette donnée pour en afficher d'autre. Mais comme le programme intercepte la valeur de 26.3 comme 26.299... les autres donnée ne sont donc pas affichée. De plus c'est valeur doit etre de type numérique et non chaine de caractère parce que j'utilise le tri numérique pour ordonnancer ces données...

Le pire c'est quand je fais un query sur ma table du style select * from clc where (cas = 26.3), le query me trouve l'enregistrement.

Quelqu'un saurait me dire pourquoi la basse de donnée me donne la valeur de 26.3 alors que le programme affiche la valeur de 26.299...

Merci
Jerome
Afficher la suite 

Votre réponse

10 réponses

Meilleure réponse
cs_Loda 900 Messages postés vendredi 3 novembre 2000Date d'inscription 30 juillet 2009 Dernière intervention - 7 août 2006 à 18:57
3
Merci
Salut,

Cela vient de la manière dont est stocké la valeur en mémoire (du PC).

Pour faire dans le simplifié, Les nombres flotant sont stocké sous la forme "scientifique" cad 'base' x 10~'Puissance' (+signe)

La base est stocké avec un nombre finit de bit (disons 15 pour l'exemple).

Donc quand tu écrit 26.3, il vas arrondire la base (263) au nombre le plus pres d'une puissance de 2 (1 à 2^15-1).

Après quand tu "relit" la valeur, il te retourne toute la précision qu'il a (26299...). Même celle que tu ne lui a pas donné.

C'est pour ça qu'il ne FAUT JAMAIS FAIRE DE TEST D'EGALITE AVEC DES FLOTANT !!!!

C'est aussi pour ça que tu peut additionner 1e-10 à une var floatant qui vaut 10e40 pendant toute une journée sans que la var ne change de valeur.

fait un test genre :

(cas < Limit + Epsilon) and (cas > limit - Epsilon)

avec un Epsilon qui vaut genre 0.002. (enfin, ça dépend de bcp de choses)

Chaque fois que possible, évite les type flotant, remplace les par des integer avec une ponderation (facteur).


"De plus c'est valeur doit etre de type numérique et non chaine de caractère parce que j'utilise le tri numérique pour ordonnancer ces données..."

je connais pas les détail de ton cas, mais il y a surement un moyen de le lire directement en floatant.

bon code,

Merci cs_Loda 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 96 internautes ce mois-ci

Commenter la réponse de cs_Loda
Meilleure réponse
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 8 août 2006 à 05:22
3
Merci
utilise la virgule fixe.

26.3 = 2630/100 << depend de l'interval Min..Max des chiffres et de la precision voulue 1..n decimales

stockage en entiers : round(Float*100)

si je joue dans l'interval : 0..1000 avec precision maxi de 3 decimale, je multiplie par 1000
Fin := round(F*1000);
Fout := Fin/1000;

le tri de chaine en valeur flottante risque de faire n'importe quoi ...

en tout cas on index pas des valeurs avec des flottant justement a cause de ça.

champs ID : int / unique / auto increment / non null
champs Valeur : float / null

<hr size="2" width="100%" />Croc (click me)

Merci f0xi 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 96 internautes ce mois-ci

Commenter la réponse de f0xi
ethan_decoster 38 Messages postés mardi 31 janvier 2006Date d'inscription 4 avril 2008 Dernière intervention - 7 août 2006 à 18:52
0
Merci
Ah oui une chose importante peut etre, la valeur de 26.3 dals la base de donnée est recupérée avec le composant DBEdit. C'est peut etre ca le probleme... Je check et vous tiens au courant...

Si quelqu'un, trouve avant moi, merci de poster vos commentaires...

Jerome
Commenter la réponse de ethan_decoster
ethan_decoster 38 Messages postés mardi 31 janvier 2006Date d'inscription 4 avril 2008 Dernière intervention - 7 août 2006 à 19:03
0
Merci
Y pas une solution pour lire le nombre comme il est tape dans la base de donnée??
Commenter la réponse de ethan_decoster
cs_Loda 900 Messages postés vendredi 3 novembre 2000Date d'inscription 30 juillet 2009 Dernière intervention - 7 août 2006 à 19:05
0
Merci
oui, il faut utiliser un champ string pas floatant.

ou si t'as toujours la même précision lors de la saisie, fait une routine de formatage.
Commenter la réponse de cs_Loda
ethan_decoster 38 Messages postés mardi 31 janvier 2006Date d'inscription 4 avril 2008 Dernière intervention - 8 août 2006 à 00:48
0
Merci
Avec une chaine string, tu sais faire un tri numerique sur les donnees??
Commenter la réponse de ethan_decoster
cs_Loda 900 Messages postés vendredi 3 novembre 2000Date d'inscription 30 juillet 2009 Dernière intervention - 8 août 2006 à 11:51
0
Merci
au pire des pire, fait un champs en flotant que tu utilise pour le tri et un en string pour avoir ta "saisie". (très moche)

Mais j'éviterais si j'étais toi, y a surement un moyen de résoudre ton problème en changeant deux-trois trucs dans ton system.

De toute façon, tu peux marquer 'dommage' pour faire un test d'égalité (unique) avec un flotant.
Commenter la réponse de cs_Loda
ethan_decoster 38 Messages postés mardi 31 janvier 2006Date d'inscription 4 avril 2008 Dernière intervention - 8 août 2006 à 17:45
0
Merci
oui c'est vrai que c'est moche comme solution. J'ai fait changer le fusil d'epaule de loa sncb qui a abandonner le projet de mettre un cas intermedaire. Ex: 26 26BIS et 27 (si je les mettais en chaine de caractere) j'aurais pas eu cet ordre la. Maintenant la solution etait de garder le champs numerique mais de mettre 26 26,1 et 27 dans la base de donnée. Mais le projet a ete abandonné. Merci pour ton explication Loda j'avais pas capté cela comme ca mais c'est vrai que les float c'est de la M....

Jerome
Commenter la réponse de ethan_decoster
cs_Loda 900 Messages postés vendredi 3 novembre 2000Date d'inscription 30 juillet 2009 Dernière intervention - 8 août 2006 à 18:25
0
Merci
de rien.

si j'ai bien compris, tu utilise la partie fractionnaire de ton float pour distinguer des cas?!

pourquoi tu n'utilise pas un champs supplémentaire ? cela te permeterait de faire ton trie facilement.

(les float c'est fait pour manipuler des valeurs floattant. faut pas s'en servire pour autre choses.)

bon code,
Commenter la réponse de cs_Loda
twh19 5 Messages postés mercredi 4 août 2004Date d'inscription 5 janvier 2009 Dernière intervention - 17 oct. 2007 à 18:30
0
Merci
procedure TForm1.Button1Click(Sender: TObject);
var a,b,c,d,e,f,n,o,k: string;
    i,j,g,m,x,y,v: integer;
    tr: boolean;
begin
j := 0;
k := '';
tr := false;while (j <length(edit1.Text)) and (tr false) do
   begin
     k := edit1.Text[j];
     if k = '.' then
       begin
        tr := true;
        v := j;
       end;
     j := j + 1;
   end;
if tr = true then
begin if (length(edit1.Text) - v 1) or (length(edit1.Text) - v 2)  then
  edit2.text := edit1.Text
else
begin
i := 1;
m := 0;
c := '';
b := '';
while i <= length(edit1.Text) do
  begin
     c := edit1.Text[i];
     b := b + c;
      if c = '.' then
        begin
          a := b;
          m := i;
        end;
     i := i + 1;
  end;
d := edit1.Text[m + 1];
e := edit1.Text[m + 2];
f := edit1.Text[m + 3];
n := d + e;
if StrToInt(f) >= 5 then
  begin
    g := StrToInt(n) + 1;
    n := IntToStr(g);
    if g = 100 then
        begin
          o := '';
          for x := 1 to m - 1 do o := o + a[x];
          y := StrToInt(o) + 1;
          edit2.Text := IntToStr(y);
        end
       else
           edit2.Text := a + n;
  end
     else
       begin
         edit2.Text := a + n;
       end;
end;
end
  else
    edit2.text := edit1.Text;
end;

The joy of the life is to do a work that nobody made and that nobody it imagined
Commenter la réponse de twh19

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.