Portage d'un algorithme écrit pour Carbon
macvelotte
Membre
C'est une suite à vos réponses pertinentes.
Voici un extrait de code "C"
Voici l'équivalent "Objective C" (selon moi ...
Je sais qu'il y a beaucoup à redire et que je me fourvoie certainement !
Ma question : qu'est-ce qui ne va pas?
Voici un extrait de code "C"
<br />void soustraction(int soustab[],int lim)<br /><br />{ int i;<br /> <br /> for (i=nchif;i>=lim;i--)<br /> {<br /> pitab[i]=pitab[i]-soustab[i];<br /> if (pitab[i]<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>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<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?
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
- 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
le code objective-C fait exactement le même chose ! mais je ne sais pas le faire plus simple !
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
La différence, elle s'appelle [tt]else[/tt]... Et ça ne m'explique toujours pas l'algo.
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).
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 ?
[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]
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.
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 :
C'est un gros classique, mais c'est toujours bon à connaà®tre
+
Chacha
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.
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
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.
elle s'appelle main!
::)
Ca ira plus vite je pense...
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.
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...
[Fichier joint supprimé par l'administrateur]
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.
[Fichier joint supprimé par l'administrateur]
main.c:217: warning: return type of 'main' is not 'int'
mais il ne se passe rigoureusement rien ! ????
[EDIT]
Bon OK c'était pô bien sympa comme remarque, mais tellement tentant... désolé :P
-->[]