Récupération des valeurs entieres et decimales d'un float

Eddy58Eddy58 Membre
19:02 modifié dans API AppKit #1
J'ai besoin de convertir un float en string, par exemple avec la valeur 234.45, sous la forme : 0000000000023445
C'est une NSString de 16 caractères en tout.
Actuellement, je transforme d'abord le float en NSNumber, puis en NSString.
A noter que si le NSNumber a une partie décimale égale à  0, la NSString retournée ne comporte pas la partie décimale, donc pas de virgule.
Je fais donc ma petite cuisine :P, en scannant la NSString, puis en repérant à  quel valeur d'index est la virgule (et, s'il y en a une), je construit ensuite à  partir des résultats du scan ma chaine comme sur le modèle plus haut.
Je voudrais savoir s'il y a un moyen plus élégant de récupérer les deux parties d'un float, ou d'un NSNumber, ensuite je convertis les deux valeurs retournées en NSString, et comme ça ca m'éviterait de faire un scan...J'ai cherché mais je n'ai rien trouvé, ou alors je suis passé à  côté.... :)
«1

Réponses

  • BruBru Membre
    19:02 modifié #2
    J'ai du mal à  comprendre le but du jeu...

    .
  • Eddy58Eddy58 Membre
    octobre 2004 modifié #3
    :D Oui, ca peut paraà®tre bizarre Bru... ;)
    La forme particulière de la NSString : 0000000000023445, fait parti d'un tout, en faites c'est une somme d'argent. Cet exemple signifie 234 Euros et 45 Centimes. Cette forme est le modèle demandé pour les fichiers protocolaires fournis par des commerçants à  leur banque pour automatiser les virements banquaires avec leurs clients. Voilà ... :)
  • mpergandmpergand Membre
    19:02 modifié #4
    On peut bidouiller un truc en C:

    float val=1524.254;

    int entiere=val;    // convertit en int et perd donc la partie décimale  :D
    int decimale=(val-entiere)*100;  // partie décimale, x100 pour 2 chiffres apres la virgule, x1000 pour 3 chiffres ...

    y a surement des fonctions en C qui font la même chose, mais je ne les connais pas  ;)
  • odjauodjau Membre
    19:02 modifié #5
    A partir  du float 234,45, multiplié par 100 --> 23445

    En utilisant la méthode
    stringWithFormat:@%016d,23445;
    On obtient : 0000000000023445

    Enfin, chez moi ça marche :-\
  • Eddy58Eddy58 Membre
    19:02 modifié #6
    Ok merci Ptit Bras ! :D
    Ca marche impeccable, ma routine a maigrie d'un coup. 8) :spot:
    Je ne pense pas assez à  ce genre de méthodes en effet....efficace en tout cas :)
    <br />-(NSString *)faireStringMontant:(float)montant<br />{<br /> NSString *montantString;<br />  int montantX100;<br /><br />    montantX100=(int)(montant*100);<br />   montantString=[NSString stringWithFormat:@&quot;%016d&quot;,montantX100];<br /> <br />  return montantString;<br />}<br />
    


    Merci aussi à  Mpergand, qui avait un début de solution, mais en faisant des recherches ensuite, j'ai trouvé la fonction C modf(), qui splite l'integer et le fractional. Seulement elle prend des valeurs doubles, donc j'avais un problème lors du casting mon float en double, qui   transformait le fractional en une valeur approchée.... :-\
    <br />float valFloat=234.45;<br />double integer,fractional;<br />double valDouble=(double)valFloat;<br />fractional=modf(valDouble,&amp;integer);<br />
    
     
  • Eddy58Eddy58 Membre
    19:02 modifié #7
    Si c'est pas malheureux ça !  :'(
    J'ai une erreur d'un centime qui se présente assez souvent, cela invalide la routine :(...va falloir que je revienne à  l'ancienne forme, en faisant tout avec les NSString. Merci pour tout quand même. :)
  • TiffTiff Membre
    19:02 modifié #8
    Toujours eu des problèmes de décimales avec les float, pourquoi es-tu obligé de travailler avec les float plutôt que les double ?
  • Eddy58Eddy58 Membre
    19:02 modifié #9
    Bon j'ai finalement pu me débrouiller avec le stringWithFormat. :) Au lieu de faire un casting int, je garde mon float, et je change sa précision en la mettant à  0 dans le formatage.
    <br />-(NSString *)faireStringMontant:(float)montant<br />{<br />     NSString *montantString;<br />  float montantX100;<br /><br />  montantX100=montant*100;<br />  montantString=[NSString stringWithFormat:@&quot;%016.0f&quot;,montantX100];<br />       <br />  return montantString;<br />}<br />
    


    Là  ça roule, plus d'erreur de centimes. 8) :D

    dans 1098264252:

    Toujours eu des problèmes de décimales avec les float, pourquoi es-tu obligé de travailler avec les float plutôt que les double ?

    Et bien les valeurs que je vais récupérer dans les bdd sont des float....Ce sont des sommes d'argent, donc ca ne demande pas une super précision... :)
  • TiffTiff Membre
    19:02 modifié #10
    ca ne demande pas une super précision...

    Oui, mais même pour des nombres à  deux décimales, les float ne me semblent pas fiables. Toutes mes petites applis qui parlent d'argent utilisent des double, pour éviter les aberrations du type 2*3,15¤=6,31¤. Je ne sais pas si ça vient des formatters ou des floats, mais c'est assez pénible.
  • 19:02 modifié #11
    dans 1098271172:

    ca ne demande pas une super précision...

    Oui, mais même pour des nombres à  deux décimales, les float ne me semblent pas fiables. Toutes mes petites applis qui parlent d'argent utilisent des double, pour éviter les aberrations du type 2*3,15¤=6,31¤. Je ne sais pas si ça vient des formatters ou des floats, mais c'est assez pénible.


    Le problème de 2* 3,15 vient des virgules flotantes car en C pur ce problème arrive régulièrement.  Les formatters sont donc normallement hors de cause ;D De mémoire, c'est le fait que 3.15 est défini par 3.155... Il faudrait voir en mettant 3.150

    Et pour tout ce qui touche conversion numérique,chaine, hexa et des formatages de bases n'oubliez pas que cela utilise exactement le même format que les printf et autres scanf du C.

    http://membres.lycos.fr/tonysoueid/cour_c/cour_1/chap04.html

  • Eddy58Eddy58 Membre
    19:02 modifié #12
    dans 1098271172:

    ca ne demande pas une super précision...

    Oui, mais même pour des nombres à  deux décimales, les float ne me semblent pas fiables. Toutes mes petites applis qui parlent d'argent utilisent des double, pour éviter les aberrations du type 2*3,15¤=6,31¤. Je ne sais pas si ça vient des formatters ou des floats, mais c'est assez pénible.

    Ha oui ? Je n'ai pas de problème de ce côté là , je valide les valeurs par des NSNumberFormatter. Mes calculs sont justes égalements...les seuls problèmes que j'ai rencontré jusqu'ici sur les floats sont dus aux castings.:)
  • TiffTiff Membre
    19:02 modifié #13
    Tous les tutoriaux du type Currency Converter que j'ai pu voir, avec ou sans formatter, avec ou sans binding, plantaient à  un moment ou à  un autre, pour certaines valeurs. En creusant un peu, j'avais remarqué que quand je donnais la valeur 2,35 par exemple, elle était transformée aussitôt en 2,35001,ce qui induisait très vite des comportement étranges si on titillait un peu la bête (des trucs tout bêtes, on multiplie par 2, puis par 0.5, puis on recommence ; les erreurs de calcul deviennent très vite gênantes)

    J'suis tout seul à  avoir remarqué ça ?  ???
  • 19:02 modifié #14
    dans 1098286970:

    Tous les tutoriaux du type Currency Converter que j'ai pu voir, avec ou sans formatter, avec ou sans binding, plantaient à  un moment ou à  un autre, pour certaines valeurs. En creusant un peu, j'avais remarqué que quand je donnais la valeur 2,35 par exemple, elle était transformée aussitôt en 2,35001,ce qui induisait très vite des comportement étranges si on titillait un peu la bête (des trucs tout bêtes, on multiplie par 2, puis par 0.5, puis on recommence ; les erreurs de calcul deviennent très vite gênantes)

    J'suis tout seul à  avoir remarqué ça ?  ???


    Mais cela est normal. En C, le codage flottant permet de représenter une partie des réels  de façon approchée. C'est leur définition (j'ai retrouvé cela dans mon bouquin de C ;) )
  • ChachaChacha Membre
    19:02 modifié #15
    Bonjour,
    Oh là  là , lire "les sommes d'argent ne demandent pas beaucoup de précision", ça m'a un peu fait bondir... Les float ne peuvent pas représenter tous les nombres, ils en sont loin, donc les utiliser expose à  de multiples problèmes !

    Le simple programme suivant permet de s'en convaincre :
    #include <stdio.h>

    int main(int argc, char* argv[])
    {
      float x = 0.0;
      const float step = 0.01;
      float y = x + step;
      while(y != x)
      {
        x = y; 
        y += step;
      }
      printf("x = %f\ny = %f\n%f+%f = %f\n", x, y, x, step, x+step);

      return 0;
    }

    Une petite compilation sans aucune optimisation :

    gcc -Wall -ansi -pedantic -O0 -o e main.c

    et on obtient :
    262144.000000+0.010000 = 262144.000000

    Voilà ... 262144.01 n'est pas représentable par un float. (d'accord, j'aurai jamais ça sur mon compte en banque)

    Avec les double, c'est mieux, mais tous les nombres ne sont pas représentables non plus. En toute rigueur, il faudra utiliser une bibliothèque de calcul mathématique de précision arbitraire. Bon, là , dans le contexte, je pense que les double sont suffisants, mais les float sont clairement à  éviter.
  • Eddy58Eddy58 Membre
    19:02 modifié #16
    dans 1098371660:

    mais les float sont clairement à  éviter.


    Oui c'est tellement à  éviter, que mon appli marche impeccable, avec des bdd contenant pas mal de float..... :D ;D ;D
    Le soft est en version bêta, et fonctionne comme une horloge, au centime près.... :spot:
  • ChachaChacha Membre
    19:02 modifié #17
    " Les gens normaux croient que si ça marche, c'est qu'il n'y a rien à  réparer.
    Les ingénieurs croient que si ça marche, c'est que ça ne fait pas encore
    assez de choses. "
    Scott Adams, Le principe de Dilbert.

    En fait, je dois être ingénieur !

    Plus sérieusement, ça coûte pas cher de convertir les float en double, et ça évite d'avoir, un jour, un problème... Mais bon, ce n'est pas mon programme non plus, alors c'est facile de critiquer.

    Bon courage pour la suite !
  • Eddy58Eddy58 Membre
    19:02 modifié #18
    Merci pour tes conseils Chacha, mais je t'assure je fais des tonnes de calculs avec mes float, dans pas mal de situation différentes, et ça marche comme un charme (testé sur plusieurs configs en plus), donc je vois pas l'intérêt de mettre des double... :)
    Tu vois je ne suis pas ingénieur, mais j'ai un principe fondamental : "Si as atteint ton objectif, c'est que tu n'as pas placé la barre assez haut".
    Ca ressemble assez au tiens... mais tu remarqueras que dans mon cas on a pas besoin d'être ingénieur pour chercher l'amélioration.....:)

    Je te souhaite bonne continuation Chacha :adios!: :D
  • ChachaChacha Membre
    19:02 modifié #19
    AaaAh, en fait j'ai des scrupules à  laisser tomber. Que se passe-t-il si tu essayes de rentrer le montant suivant dans ton logiciel :

    262144.01

    (ce nombre est tiré du programme que je proposais à  mon premier post)

    Si tu ne travailles qu'en float, le centime doit disparaà®tre. S'il ne disparaà®t pas, c'est que d'une manière ou d'une autre, le travail se fait sur des double à  un moment où à  un autre.
  • Eddy58Eddy58 Membre
    19:02 modifié #20
    Bien joué Chacha ! :)
    En effet le centime disparaà®t. Tu as réussi à  me convaincre. C'est vrai que le soft n'est pas fait pour accueillir de telles valeurs, aussi les tests n'ont pas laissés transparaitre ce défaut.
    Il est hors de question que je laisse le soft avec une telle abération....
    Dès demain je fait un Find&Replace sur tout mes floats.... :)

    Allez viens Chacha c'est ma tournée, on va fêter ça, boire aux double ;),  et à  mon galon de Cacaoculteur !  :D :trinque: :trinque:

    Et puis aussi....bienvenu sur Objective-Cocoa !  :D
  • ChachaChacha Membre
    19:02 modifié #21
    Bon ben je suis content alors, parce qu'il me semblait bien que ça ne pouvait pas marcher, alors ça m'embêtait de ne rien faire... D'ailleurs ça ne t'a pas échappé, je suis nouveau sur  Objective-Cocoa... je me suis inscrit rien que pour toi !

    Maintenant que c'est fait, je posterai sans doute plus souvent...

    +
    Chachaaaa
  • Eddy58Eddy58 Membre
    19:02 modifié #22
    dans 1098427415:

    Bon ben je suis content alors, parce qu'il me semblait bien que ça ne pouvait pas marcher, alors ça m'embêtait de ne rien faire...


    Bon comportement Chacha !
    Dommage que tout le monde ne réagit pas ainsi.
    En effet, et j'en suis certain, il y a beaucoup de gens qui viennent sur les forums (pas celui-ci en particulier), en visiteur et lecteur, sans participer, alors que parfois ils ont la solution à  un problème, ou quelque chose à  dire pour faire avancer un schmilblick (je sais plus si c'est comme ça que ca s'écrit ?). :-\

    dans 1098427415:

    D'ailleurs ça ne t'a pas échappé, je suis nouveau sur  Objective-Cocoa... je me suis inscrit rien que pour toi !

    Je suis flatté :D

    dans 1098427415:

    Maintenant que c'est fait, je posterai sans doute plus souvent...
     
    Mais j'y compte bien Chacha, et tout le monde ici t'encourage à  le faire.  :D
  • ClicCoolClicCool Membre
    19:02 modifié #23
    Salut :)

    Je me joint avec force au message de Bienvenu à  toi chacha :D

    J'ai suivi avec beaucoup d'intérêt vos échanges.

    J'ajoute à  ce qu'a dit Eddy que ceux qui ont quelque chose à  ajouter aux échanges ont bien tord de nous en priver, mais aussi que ceux qui ont des questions complémentaires à  poser sur un sujet ont bien tord aussi de nous en priver.
    En effet si quelque chose n'est pas clair pour vous dites vous bien qu'il y a de grosses chances que vous ne soyez pas seuls et que votre question permette à  tous de mieux apréhender le sujet (y compris pour ceux qui ne s'étaient même pas rendu compte que c'était pas si clair pour eux aussi ;) )

  • TiffTiff Membre
    19:02 modifié #24
    dans 1098470114:

    En effet si quelque chose n'est pas clair pour vous dites vous bien qu'il y a de grosses chances que vous ne soyez pas seuls et que votre question permette à  tous de mieux apréhender le sujet (y compris pour ceux qui ne s'étaient même pas rendu compte que c'était pas si clair pour eux aussi ;) )


    On croirait entendre un prof  ;D
    Eh ! C'est les vacances ! :spot:
  • ClicCoolClicCool Membre
    19:02 modifié #25
    dans 1098476023:

    dans 1098470114:

    En effet si quelque chose n'est pas clair pour vous dites vous bien qu'il y a de grosses chances que vous ne soyez pas seuls et que votre question permette à  tous de mieux apréhender le sujet (y compris pour ceux qui ne s'étaient même pas rendu compte que c'était pas si clair pour eux aussi ;) )


    On croirait entendre un prof  ;D
    Eh ! C'est les vacances ! :spot:

    T'as raison!
    C'est pas à  toi que je vais expliquer l'influence de notre côté enseignants ;)

    Pour ce qui est des vacances par contre ... on croirait entendre un prof du scolaire ;D
    Parce que à  la Fac c'est pas les vacances :( (en tous cas à  Marseille)
  • TiffTiff Membre
    19:02 modifié #26
    Ouais, ben j'espère ne pas passer toutes mes vacances sous la float.  :sors:
  • ClicCoolClicCool Membre
    19:02 modifié #27
    dans 1098479123:

    Ouais, ben j'espère ne pas passer toutes mes vacances sous la float.  :sors:


    Vas au bar on t'y servira un double ;D on the rock's
  • 19:02 modifié #28
    Quand tu vas dans la float, c'est en short? Ou tu préfères porter du long?
  • TiffTiff Membre
    19:02 modifié #29
    Ben, plutôt en string  ;D
  • ClicCoolClicCool Membre
    19:02 modifié #30
    dans 1098484912:

    Ben, plutôt en string  ;D


    olala arrêtes ton char qu'on voit ça ;D
  • TiffTiff Membre
    19:02 modifié #31
    Le string, faut pas en abuser, ça fait mal à  l'array.
Connectez-vous ou Inscrivez-vous pour répondre.