Portage d'un algorithme écrit pour Carbon

macvelottemacvelotte Membre
22:43 modifié dans Actualités #1
C'est une suite à  vos réponses pertinentes.

Voici un extrait de code "C"
<br />void soustraction(int soustab&#91;],int lim)<br /><br />{ int i;<br />	<br />	for (i=nchif;i&gt;=lim;i--)<br />	{<br />	pitab[i]=pitab[i]-soustab[i];<br />	if (pitab[i]&lt;0)<br />		 {<br />		 pitab[i]=pitab[i]+ base;<br />		 pitab[i-1]=pitab[i-1]-1;<br />		 } <br />	 }<br />}<br />


Voici l'équivalent "Objective C" (selon moi ...
<br />-(void)soustractiontab<br />{<br />	unsigned istab;<br />	int x1,x2,x3,retsous;<br />	NSNumber *xpitab;<br />	retsous=0;<br />	istab=dimtabs;<br />	while (istab&gt;rang)<br />		{<br />		istab--;<br />		x1=[(NSNumber *)[tab objectAtIndex:istab] intValue];<br />		x2=[(NSNumber *)[pitab objectAtIndex:istab] intValue];<br />		x3=x2-x1-retsous;<br />		if (x3&lt;0)<br />			{<br />			x3=x3+base;<br />			xpitab=[[NSNumber alloc] initWithInt:x3];<br />			[pitab replaceObjectAtIndex:istab withObject:xpitab];<br />			retsous=1;<br />			}<br />		else<br />			{<br />			xpitab=[[NSNumber alloc] initWithInt:x3];<br />			[pitab replaceObjectAtIndex:istab withObject:xpitab];<br />			retsous=0;<br />			}<br />		[xpitab release];<br />		}<br />}<br /><br />


Je sais qu'il y a beaucoup à  redire et que je me fourvoie certainement !
Ma question : qu'est-ce qui ne va pas?
«1

Réponses

  • AliGatorAliGator Membre, Modérateur
    22:43 modifié #2
    OK. Alors :
    - tu pourrais expliquer ton algo (avec des mots et des étapes) ? parce que un algo déjà  implémenté est toujours plus hard à  comprendre que l'explication de l'algo lui-même ;D
    - ton implémentation d'algo en C et en ObjC ne se ressemblent pas du tout (en C tu fais une boucle sur i, puis une soustraction, et 2 actions sur le résultat est négatif, en ObjC tu fais carrément plus de trucs, comme des actions si le résultat est positif, etc)

    - Récupérer l'objet pour le caster en NSNumber* (j'imagine que ce casting est juste pour éviter un warning lors de la compilation), pour lui envoyer intValue... et de même que (et surtout) allouer un NSNumber à  chaque fois, tout ça pour pouvoir le stocker dans ton tableau... c'est un peu dommage parce que ce sont des opérations coûteuses (enfin relativement, je veux dire par rapport à  un algo tout-en-C) pour pas grand chose.
    En effet tu manipules beaucoup -- même intensivement -- tes nombers de ton tableau, tu les remplaces, etc, et à  chaque fois tu alloues des nouvelles instances de nouveaux objets : manipulation de bcp de gros truc vu l'intensivité des manipulations.

    - Et puis alors l'algo en ObjC est loin d'être clair : un [pitab release] dans le while alors qu'il n'est pas alloué dans le while, un tableau tab qui sert dans la version ObjC alors qu'il n'y a pas de trace d'équivalent dans l'algo en C...

    - Et enfin pour de l'algorithmie, encore plus lorsque c'est de l'intensif comme ça, passer par les NSNumber, NSArray & co n'est pas forcément de toute façon ce qu'il y a de plus optimisé vu le le nombre important de manipulations que tu en fais : pourquoi ne pas rester sur un tableau de type C ??

    Bref, explique nous ton algo avec des mots, explique nous aussi pourquoi le code C et le code ObjC se ressemblent si peu en terme d'algo, et pourquoi tu t'entête à  utiliser des objets lourds lorsque la manipulation est si intensive, avec des allocations très nombreuses (parce que l'algo le veux, sans doute ?) etc
  • macvelottemacvelotte Membre
    22:43 modifié #3
    <br />void soustraction(int soustab&#91;],int lim) //les éléments du tableau soustab sont soustraits<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  //des éléments du tableau pitab<br /><br />{ int i;<br />	<br />	for (i=nchif;i&gt;=lim;i--)&nbsp;  // on commence par la fin de tableau comme dans une<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // soustraction à  la main. On s&#39;arrête quand les éléments<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // situés le plus à  gauche sont tous nuls (i&gt;=lim).<br />	{<br />	pitab[i]=pitab[i]-soustab[i];<br />	if (pitab[i]&lt;0)<br />		 {<br />		 pitab[i]=pitab[i]+ base;&nbsp; //il faut tenir éventuellement compte d&#39;une retenue.<br />		 pitab[i-1]=pitab[i-1]-1;<br />		 } <br />	 }<br />}<br />
    

    le code objective-C fait exactement le même chose ! mais je ne sais pas le faire plus simple !
  • AliGatorAliGator Membre, Modérateur
    22:43 modifié #4
    Heu c'est pas de l'explication d'algo ça ;)

    Et dans ce cas pourquoi dans ton code C tu n'as qu'une condition "< 0" et dans ton code ObjC tu as 2 conditions, "< 0" et "> 0" ? ???

    Présente-nous ton algo tel que tu l'as lu avant de l'implémenter, textuellement quoi.

    Ou alors pars sur un développement limité de PI, c'est presque aussi simple ;)
  • macvelottemacvelotte Membre
    22:43 modifié #5
    Je ne vois pas la différence ...
  • AliGatorAliGator Membre, Modérateur
    22:43 modifié #6
    Alors on est mal barrés, si tu vois pas la différence...

    La différence, elle s'appelle [tt]else[/tt]...
    else<br />	{<br />	xpitab=[[NSNumber alloc] initWithInt:x3];<br />	[pitab replaceObjectAtIndex:istab withObject:xpitab];<br />	retsous=0;<br />	}
    
    Et ça ne m'explique toujours pas l'algo.
  • macvelottemacvelotte Membre
    22:43 modifié #7
    J'ai écrit comme ça parce que je n'arrive pas à  trouver la solution équivalente en ObjC !

    Mon algo de calcul de pi est la formule de Gauss :
    pi = 48 artan(1/18) + 32 artan(1/57) - 20 artan(1/239)

    et le segment de calcul que je donne fait partie de la dernière série atan(1/239).
  • LeChatNoirLeChatNoir Membre, Modérateur
    22:43 modifié #8
    Bon je ne sais pas si je veux tout comprendre mais ce qui me chifonne un peu (outre le fait que les 2 algos semblent effectivement différends), c'est que ta fonction de soustraction, tu devrais la garder telle quelle non (en C) ?

    Je serais toi, je garderai tout mon code C et je ne ferai qu'ajouter un "convertisseur" qui lit ton tableau C et créer une chaine de caractère pour l'affichage.

    Tu minimises le travail et gardes ton code optimisé du départ.

    Non ? J'ai manqué un épisode ?
  • macvelottemacvelotte Membre
    22:43 modifié #9
    oui, mais ça ne marche pas !
  • Eddy58Eddy58 Membre
    22:43 modifié #10
    Je pense que tu devrais utiliser un code dans le genre, pour convertir ton tableau d'int en NSString : :)
    [tt]
      int pitab[nbDecimales];      // Ton tableau de décimales PI obtenu avec ton algo en C
    char pitabChar[nbDecimales]; // Chaine de caractère C résultante
    int j;

    for (j=0;j<nbDecimales;j++)
    {
    sprintf(&pitabChar[j],"%d",pitab[j]);  // Transformation des int en char
    }

    NSString *piString=[NSString stringWithCString:pitabChar]; // On fait la NSString
    NSLog(@Pi String:%@",piString);
    [/tt]
  • AliGatorAliGator Membre, Modérateur
    22:43 modifié #11
    Macvelotte : on ne dit pas "ça marche pas", mais "j'ai pas réussi à  le faire"  ;) ;D

    J'allais précisément poster ce genre de solution, Eddy, sauf que je serais passé par [tt]stringWithCharacters:(const unichar *)chars length:(unsigned)length[/tt] et non pas stringWithCString.
    Ou alors faut penser à  mettre un '\0' (caractère NULL) après le dernier caractère de la chaà®ne (terminateur de chaà®ne C)... ce que tu as oublié, Eddy...  ::) :P

    Vu que de toute façons le calcul des décimales de PI prend, quelle que soit la méthode, pas mal de temps, autant garder l'algo en C. En ObjC il n'en serait que plus lent, loin d'être 120x plus lent, mais au moins 2 ou 3x vu les manipulations intensives de nombres.
  • ChachaChacha Membre
    22:43 modifié #12
    Salut,
    Je n'ai pas suivi ce thread ni regardé le code, mais j'ai cru comprendre que les décimales sont stockées sous forme de tableau de chiffres (chaque chiffre étant compris entre 0 et 9) ?

    Dans ce cas, on peut faire encore mieux :
    <br />int pitab[nbDecimales];      // Ton tableau de décimales PI obtenu avec ton algo en C<br />char pitabChar[nbDecimales+1]; // Chaine de caractère C résultante<br /><br />int j;<br />for (j=0;j&lt;nbDecimales;j++)<br />&nbsp; pitabChar[j] = pitab[j]+&#39;0&#39;; //addition du code ascii<br />pitabChar[nbDecimales] = 0; //caractère de fin de chaà®ne C<br />	<br />NSString *piString=[NSString stringWithUTF8String:pitabChar]; //sous Tiger, stringWithCString est deprecated<br />NSLog(@&quot;Pi String:%@&quot;,piString);<br />
    


    C'est un gros classique, mais c'est toujours bon à  connaà®tre

    +
    Chacha
  • Eddy58Eddy58 Membre
    janvier 2006 modifié #13
    dans 1138032723:

    Ou alors faut penser à  mettre un '\0' (caractère NULL) après le dernier caractère de la chaà®ne (terminateur de chaà®ne C)... ce que tu as oublié, Eddy...  ::) :P

    Oui, c'est une mauvaise habitude chez moi. ;D
    Mais c'est vrai que passer par stringWithCharacters: est plus pratique. Et la solution de Chacha est pas mal aussi. :)
  • AliGatorAliGator Membre, Modérateur
    22:43 modifié #14
    Arf mince j'ai pas compris tout de suite la différence...
    En fait j'avais lu qu'en diagonale ton code, Eddy : moi j'aurais fait comem Chacha avec le [tt]+'0'[/tt] et non pas le sprintf, puisqu'on sait que les caractères sont d'origine des chiffres donc entre 0 et 9 ;)
  • macvelottemacvelotte Membre
    22:43 modifié #15
    Aligator : conserver mon algo en C veut dire que je peux faire un copier coller de mon listing C dans le projet Cocoa ???
  • AliGatorAliGator Membre, Modérateur
    22:43 modifié #16
    ???

    en heu, bien sûr, on a toujours pu intégrer du code C dans un projet Cocoa. Il suffit de mettre le code dans un fichier ".c" séparé, le header de la fonction dans un fichier ".h", et dans ton ".m" où tu veux utiliser ton algo/appeler la fonction, tu fais un import de ton ".c"

    Recherche sur OC y'a déjà  qques exemples.

    dans 1137837098:

    [...]mais pour des algorithmes le C reste imbattable (exception faite de l'assembleur, mais c'est indigeste).
    [...]
    Mais le "mieux" dans ce genre de cas est de faire ton algorithme en C et convertir le résultat final en NSString...

    dans 1138008757:
    [...] faire la routine d'aggrégat en C et convertir et afficher uniquement à  la fin risque de grandement améliorer le truc et de te rendre tes anciennes performances. (NSString et NSArray, plutot lourds à  manipulers).
    [...]
    Mais comme Obj C permet d'encapsuler très facilement du C, ca peut être un moyen d'optimiser qques routines particulières !
  • janvier 2006 modifié #17
    Euh même pô pas la peine de faire un fichier .c... Tout manuel d'intro à  l'objective-c commence par "L'Objective-C est une extension du C" autrement dit, tu peux mettre du code C directement dans l'implémentation d'une méthode, sans même passer par le .c (qui ne se justifie vraiment que si tu veux réutiliser ce code dans une appli non cocoa), tout comme tu peux implémenter des fonctions C directement dans le .m.
  • AntilogAntilog Membre
    22:43 modifié #18
    De toutes façons, tout programme ObjectiveC contient au moins une fonction C:
    elle s'appelle main!
    ::)
  • macvelottemacvelotte Membre
    22:43 modifié #19
    J'ai repris mon algo en C et j'ai au moins 50 messages d'erreur à  la compilation !

  • Eddy58Eddy58 Membre
    22:43 modifié #20
    Peux tu nous donner un aperçu de tes messages d'erreur ? :o
  • LeChatNoirLeChatNoir Membre, Modérateur
    22:43 modifié #21
    oui ou envoies carrément ton projet si c'est pas top secret...
    Ca ira plus vite je pense...
  • macvelottemacvelotte Membre
    22:43 modifié #22
    J'abandonne la poursuite de ce calcul en ObjC : je vais chercher à  me procurer CodeWarrior (j'ai une ancienne version qui ne fonctionne pas sous OS X) et je reverrai ce problème en C.

    Il me semble que ObjC n'est pas fait pour la manipulation rapide de nombres dans des tableaux. Et si ça ne marche pas, je "switcherai" pour un PC merdique où je pourrai faire ces calculs.
  • AliGatorAliGator Membre, Modérateur
    janvier 2006 modifié #23
    (soupir)

    Au fait, pourquoi tu ne commences pas par migrer ton programme CodeWarrior vers XCode (cf la doc Apple) ?

    Quand je pense que c'est sans doute uniquement les headers que tu as oublié d'inclure...
    mig_import_assistant.gif
  • macvelottemacvelotte Membre
    22:43 modifié #24
    J'ai essayé de faire la migration, mais ça ne marche pas !
  • macvelottemacvelotte Membre
    22:43 modifié #25
    Voici le programme C que je voudrais mettre en ObjC (fichier joint).

    [Fichier joint supprimé par l'administrateur]
  • AliGatorAliGator Membre, Modérateur
    janvier 2006 modifié #26
    dans 1138032723:

    Macvelotte : on ne dit pas "ça marche pas", mais "j'ai pas réussi à  le faire"  ;) ;D
    (bis repetita) :P
  • AliGatorAliGator Membre, Modérateur
    janvier 2006 modifié #27
    Tiens, du peu que j'ai vu vite fait ton programme dans le .txt, c'est pas à  mon avis tant ton algo qui marche pas, c'est ta fonction initialisation() qui est sans doute censée créer une "interface graphique" en utilisant un truc que je ne connais pas spécialement. (SIOUXMachin & co)

    Si tu enlèves le code de InitGraf (compris) au for (non compris) dans la fonction initialisation, et que tu enlèves SIOUX.h déjà ...
    En plus tu dois pouvoir enlever AppleEvents.h et QuickDraw.h aussi car je ne vois pas à  quoi ils servent dans ton algo (quel besoin des AppleEvents et de QuickDraw opur calculer les décimales de PI ? ???)
    Voilà , déjà  tu compiles ça comme un programme C de base et ça devrait aller mieux

    Une fois que c'est fait, tu pourras t'atteler à  mettre une GUI à  ton programme, à  savoir utiliser autre chose que les printf & co pour l'affichage, mais bon.

    [EDIT]
    Je viens de faire le test alors que je suis sous Windows, avec Visual C++ 6 (oui, désolé, j'ai honte, mais j'ai pas encore le droit à  un Mac pour le taf ;D), et en faisant ce que je viens de dire, le programme marche nickel chrome.

    J'ai juste copié-collé le contenu de ton fichier .txt dans un nouveau fichier C, supprimé les trucs dont je te cause, compilé, et basta...
    J'ai juste 2 warnings, mais le programme marche très bien... Alors je vois pas ce qui te pose problème, il suffisait de réfléchir 5 minutes  8)

    Je te laisse maitenant mettre une belle GUI par dessus l'algo, en remplaçant les printf.
  • mpergandmpergand Membre
    janvier 2006 modifié #28
    En faisant un projet standard tool, ça compile sans erreurs !


    [Fichier joint supprimé par l'administrateur]
  • macvelottemacvelotte Membre
    22:43 modifié #29
    à  mpergand : je fais un projet "standard tool" : ça compile avec un warning :
    main.c:217: warning: return type of 'main' is not 'int'
    mais il ne se passe rigoureusement rien ! ????
  • 22:43 modifié #30
    est-ce que tu comprends l'anglais?
  • AliGatorAliGator Membre, Modérateur
    janvier 2006 modifié #31
    dans 1138143273:

    est-ce que tu comprends l'anglais?
    (Je me poserait même parfois la question pour le français...)

    [EDIT]
    Bon OK c'était pô bien sympa comme remarque, mais tellement tentant... désolé :P
    -->[]
Connectez-vous ou Inscrivez-vous pour répondre.