[Résolu] Math.min

ancrouancrou Membre
mai 2008 modifié dans API AppKit #1
Bonjour,

Avec Java il existe la Méthode statique Math.min(val1,val2);
Et en Objective-C ?

Car j'ai 2 chiffres de type UI32_ à  comparer.
Comment faire ?
  :-\\

Réponses

  • schlumschlum Membre
    15:46 modifié #2
    Avec math.h, y a "fmin" et "fmax"

    &nbsp; &nbsp;  double fmax(double, double)<br />&nbsp; &nbsp;  double fmin(double, double)
    


    Sinon, c'est l'exemple typique pour une macro à  arguments :

    #define MIN(A,B) (((A)&lt;(B))?(A):(B))
    
  • ancrouancrou Membre
    15:46 modifié #3
    C'est au top. 

    Merci
  • AliGatorAliGator Membre, Modérateur
    15:46 modifié #4
    dans 1210761861:

    Sinon, c'est l'exemple typique pour une macro à  arguments :
    #define MIN(A,B) (((A)&lt;(B))?(A):(B))
    

    Qui est la solution à  préférer pour des UI32 puisque comme ça on reste dans le domaine des entiers non signés, alors que fmin et fmax font un cast implicite en type "double" ;)
  • ChachaChacha Membre
    15:46 modifié #5
    dans 1210767443:

    Sinon, c'est l'exemple typique pour une macro à  arguments :
    #define MIN(A,B) (((A)&lt;(B))?(A):(B))
    

    Qui est la solution à  préférer pour des UI32 puisque comme ça on reste dans le domaine des entiers non signés, alors que fmin et fmax font un cast implicite en type "double" ;)


    Moi ça m'embête toujours de conseiller une macro avec ses effets de bord (MIN(i++, j), et compagnie)
    Je propose donc :
    -soit faire appel à  Objective-C++ (dans ce cas on renomme le fichier toto.m en toto.mm et on a le droit d'utiliser std::max() et std::min())
    -soit faire appel au C99 (si je ne me trompe pas, c'est le mode par défaut en Obj-C), et on a le droit de faire des fonctions inline et surchargées pour écrire soi-même les fonctions min et max

    +
    Chacha
  • schlumschlum Membre
    15:46 modifié #6
    Ah ben sinon on peut bien entendu définir une fonction inline...

    inline UI32_ min(UI32_ a, UI32_ b)<br />{<br />&nbsp; &nbsp; return a&lt;b?a:b;<br />}
    
  • Philippe49Philippe49 Membre
    15:46 modifié #7
    dans 1210768608:


    Moi ça m'embête toujours de conseiller une macro avec ses effets de bord (MIN(i++, j), et compagnie)



    Pas d'accord, pour deux raisons :

    1) Beaucoup d'expressions du C standard restent des macros

    2) Les effets de bords ne sont pas que dans les macros
    exemple :

    int main (int argc, const char * argv[]) {
    int i=2,j=3;
    printf("%d %d\n ",i+=j,j--);

    return 0;
    }


    A l'essai, j'obtiens 4 3. :P
    Il faut donc savoir les utiliser et connaà®tre le danger des effets de bords.
  • schlumschlum Membre
    15:46 modifié #8
    Tiens, ça veut dire que les arguments supplémentaires de printf sont évalués de droite à  gauche donc... bizarre.

    Enfin c'est quand même le genre de code qu'il vaut mieux éviter  :o
  • Philippe49Philippe49 Membre
    mai 2008 modifié #9
    dans 1210837171:

    Tiens, ça veut dire que les arguments supplémentaires de printf sont évalués de droite à  gauche donc... bizarre.


    J'ai essayé depuis plusieurs ce code, et chaque fois, c'est ainsi. Ceci dit,ce n'est dit nulle part dans la norme.

    Dans ce code, il y a aussi le comportement du -- qui est rigolo, expliquable mais rigolo.

    Ce genre de problèmes est souvent masqué dans des instructions du type sprintf(s, " format ", .... )

    dans 1210837171:

    Enfin c'est quand même le genre de code qu'il vaut mieux éviter  :o

    Oui, ou alors peut-être pour taquiner ...  ::) ::)
    C'est pour cela que la réserve sur les macros me semble excessive. Je préfère dire
    "il ne faut pas utiliser un code susceptible de faire des effets de bords"

    Pour aller néammoins dans le sens de Chacha, on remarquera que certaines exrpessions comme isalpha() sont des fonctions inline appelant des macros, les arguments étant donc en quelque sorte "nettoyés" avant d'être traités par la macro.

  • schlumschlum Membre
    15:46 modifié #10
    Ah non, le comportement du "--" est tout à  fait normal ici...
    C'est post-fixé, donc évalué avant la décrémentation... qui est effective pour l'évaluation de l'argument suivant  ;) (enfin précédent du coup puisque c'est de droite à  gauche)
  • AliGatorAliGator Membre, Modérateur
    15:46 modifié #11
    Sans doute à  cause de l'empilement des arguments sur la pile lors de l'appel de la fonction C, empilement des arguments qui se fait à  l'envers.
    Avec un nombre variable d'arguments, et donc l'utilisation de va_args et va_list, on va directement lire les arguments sur la pile, l'execution des opérateurs de droite à  gauche pourrait donc être lié à  cet empilement à  l'envers, non ?
  • schlumschlum Membre
    15:46 modifié #12
    Oui mais justement, avec va_args et va_list on lit dans le sens du code si je ne m'abuse.  ;)
  • Philippe49Philippe49 Membre
    15:46 modifié #13
    dans 1210839899:

    Ah non, le comportement du "--" est tout à  fait normal ici...


    Logique certes, mais bon quand on est dans le bizarre ...

    Voilà  de la logique bizarre :

    #include <stdlib.h>
    #include <stdio.h>

    void fn(int i,int j){
    printf("%d %d\n ",i,j);
    }

    int main (int argc, const char * argv[]) {
    int i=2;
    int j;
    j=(i++,i+3);
    printf("%d %d\n",i,j);

    i=2;
    fn(i++,i+++3);
    return 0;
    }


    réponse :
    % pgm
    3 6     
    3 5      :brule:
    %

    exemples à  fuir ...
    Ouououououououarffffffffffffffff  ;D ;D ;D ;D ;D ;D ;D
  • schlumschlum Membre
    15:46 modifié #14
    Non, pour le coup ton exemple est tout à  fait logique à  nouveau  ;)
    Suffit de connaà®tre les règles de sens d'évaluation...
    () -> gauche à  droite, donc pour le premier exemple, i++ est fait d'abord, puis j=i+3=6

    arguments d'une fonction -> droite à  gauche
    i++ + 3 -> 5 (car ++ postfixé, donc incrémentation faite après l'évaluation)
    i++ -> 3 (de par l'incrémentation au dessus ; à  nouveau postfixé, donc i vaudra 4 après l'affichage)
  • schlumschlum Membre
    15:46 modifié #15
    dans 1210843314:

    Sans doute à  cause de l'empilement des arguments sur la pile lors de l'appel de la fonction C, empilement des arguments qui se fait à  l'envers.
    Avec un nombre variable d'arguments, et donc l'utilisation de va_args et va_list, on va directement lire les arguments sur la pile, l'execution des opérateurs de droite à  gauche pourrait donc être lié à  cet empilement à  l'envers, non ?


    En fait, oui, c'est logique... Peu importe le sens de va_args et va_list, les arguments ont déjà  été empilés et évalués avant même l'appel...
  • AliGatorAliGator Membre, Modérateur
    15:46 modifié #16
    dans 1210846849:

    En fait, oui, c'est logique... Peu importe le sens de va_args et va_list, les arguments ont déjà  été empilés et évalués avant même l'appel...
    C'est ça que je voulais dire oui ;) Bon ok c'est vrai qu'en fait, va_args ou arguments fixes, ça change rien au problème  du coup mais bon. Ils sont empilés en sens inverse d'abord, et du coup évalués lors de l'empilation, donc de droite à  gauche.
    Et ensuite dans la fonction on les dépile, certes de gauche à  droite (enfin celui du dessus de la pile d'abord, donc le dernier à  avoir été empilé [LIFO] = celui qui était le plus à  gauche lors de l'appel en premier), mais à  ce moment les opérateurs ont déjà  été appliqués.


    Conclusion, les arguments sont évalués de droite à  gauche, lorsqu'ils sont empilés... mais les post-incrémentations et post-décrémentations sont effectuées uniquement après le retour de la fonction. C'est bien ce que tu sembles expliquer schlum, hein ? Et ça me semble plutôt logique décrit comme tel.
    Le problème est que ça va à  l'encontre de l'exemple du [tt]printf("%d %d\n", i+=j , j--);[/tt] de Philippe49, où le "j--" est effectué qd mm avant l'appel à  la fonction, passant i+=j donc du coup 4 comme premier chiffre au printf, et non 2+3=5...

    Troublant tout ça... Même si ça n'a jamais été une bonne idée de jouer avec le feu de ce côté, ben quand même... pfiou !
  • schlumschlum Membre
    15:46 modifié #17
    Non non, les post-incrémentations / post-décrémentations sont faite juste après l'évaluation, donc entre le moment où on a empilé l'argument et le moment où on empile le suivant !

    printf("%d %d\n", i+=j , j--);

    - J'empile "j"
    - Je décrémente "j"
    - i = i+j
    - J'empile "i"
  • AliGatorAliGator Membre, Modérateur
    15:46 modifié #18
    dans 1210855065:

    Non non, les post-incrémentations / post-décrémentations sont faite juste après l'évaluation, donc entre le moment où on a empilé l'argument et le moment où on empile le suivant !

    printf("%d %d\n", i+=j , j--);

    - J'empile "j"
    - Je décrémente "j"
    - i = i+j
    - J'empile "i"
    Ah oui en effet ça colle avec tous les cas testés comme ça. Donc post-inc/déc faite après l'empilement de chaque arg, qui est faite de droite à  gauche. Et là  ça devient plus du tout logique, vu qu'on s'attendrait à  ce que la post-inc/dec soit faite au retour de fonction et pas après l'empilage de l'argument.

    C'est quand même fort, pour un sujet marqué [Résolu] depuis quelques temps qu'on arrive à  continuer si loin ;D
    Bon ben pour la peine, et vu qu'il fait encore chaud ici dehors (pourquoi on doit être enfermés dans des bureaux alors qu'on pourrait bosser sur la pelouse, hein ?), un petit  :p :p avant que le temps ne se couvre :P
  • Philippe49Philippe49 Membre
    15:46 modifié #19
    dans 1210846711:

    Non, pour le coup ton exemple est tout à  fait logique à  nouveau 


    Non, il n'y a rien de logique là -dedans, c'est simplement comme ça, et on peut trouver une raison acceptable. La norme n'impose rien (j'ai compris depuis très longtemps la différence entre j++ et ++j)
    D'ailleurs ce n'est pas la même logique pour l'expression  j=(i++,i+3), qui lui doit suivre l'ordre de la gauche vers la droite inscrit dans la norme.

    dans 1210857775:

    C'est quand même fort, pour un sujet marqué [Résolu] depuis quelques temps qu'on arrive à  continuer si loin ;D
    Bon ben pour la peine, et vu qu'il fait encore chaud ici dehors (pourquoi on doit être enfermés dans des bureaux alors qu'on pourrait bosser sur la pelouse, hein ?), un petit  :p :p avant que le temps ne se couvre :P

    Non, non, on arrêtera pas ! surtout si à  la clé il y a  :p :p :kicking:




  • schlumschlum Membre
    15:46 modifié #20
    dans 1210858377:

    dans 1210846711:

    Non, pour le coup ton exemple est tout à  fait logique à  nouveau 


    Non, il n'y a rien de logique là -dedans, c'est simplement comme ça, et on peut trouver une raison acceptable. La norme n'impose rien (j'ai compris depuis très longtemps la différence entre j++ et ++j)
    D'ailleurs ce n'est pas la même logique pour l'expression   j=(i++,i+3), qui lui doit suivre l'ordre de la gauche vers la droite inscrit dans la norme.


    Ben qu'est-ce qui n'est pas logique ?
    l'opérateur "," est bien défini dans la norme comme opérateur à  évaluation de gauche à  droite, et les arguments empilés dans le sens inverse, c'est standard aussi  ???
  • schlumschlum Membre
    15:46 modifié #21
    dans 1210857775:
    Et là  ça devient plus du tout logique, vu qu'on s'attendrait à  ce que la post-inc/dec soit faite au retour de fonction et pas après l'empilage de l'argument.


    Pourquoi donc ? Les arguments sont copiés, ce n'est pas par référence...
  • AliGatorAliGator Membre, Modérateur
    15:46 modifié #22
    dans 1210859420:

    dans 1210857775:
    Et là  ça devient plus du tout logique, vu qu'on s'attendrait à  ce que la post-inc/dec soit faite au retour de fonction et pas après l'empilage de l'argument.


    Pourquoi donc ? Les arguments sont copiés, ce n'est pas par référence...
    J'entendais plutôt ça dans le sens "c'est pas naturel" : sans trop fouiller dans la façon dont le C fonctionne et est compilé, comme "j++" est un opérateur de post-incrémentation, et "sans trop réfléchir" on se dit que ça sera incrémenté après... sous-entendu après l'exécution de la fonction.
    On est pas sensés connaà®tre forcément la façon dont le compilateur empile les arguments dans la stack pour savoir programmer, donc ce comportement là  est loin de sembler logique (pardon, "naturel") et sauter aux yeux, on s'attend plutôt à  ce que l'incrémentation se fasse à  la fin de l'instruction, "au moment du point-virgule" si je puis dire, avant de passer à  l'instruction suivante.

    Donc oui les arguments sont copiés, mais on s'attend à  ce que la post-incrémentation se fasse après... la copie de tous les arguments dans le contexte de la fonction.

    Mais bien sûr, d'un point de vue technique, vu les explications qu'on vient de fournir, c'est "logique" ou plutôt "ça s'explique vu comment le C fonctionne, avec l'empilement des arguments en ordre inverse etc", ça n'empêche que c'est pas trivial ;)
  • schlumschlum Membre
    15:46 modifié #23
    Yes  o:)
    J'avais déjà  entendu cette histoire d'empilage à  l'envers plusieurs fois...
  • AliGatorAliGator Membre, Modérateur
    15:46 modifié #24
    dans 1210890138:

    Yes  o:)
    J'avais déjà  entendu cette histoire d'empilage à  l'envers plusieurs fois...
    Ben bon je crois qu'il ne reste plus qu'à  dépiler... les verres ;D  (à  l'envers ?) :)
    :p :p
  • AntilogAntilog Membre
    15:46 modifié #25
    dans 1210925696:

    dans 1210890138:

    Yes  o:)
    J'avais déjà  entendu cette histoire d'empilage à  l'envers plusieurs fois...
    Ben bon je crois qu'il ne reste plus qu'à  dépiler... les verres ;D  (à  l'envers ?) :)
    :p :p


    Tu dois avoir pas mal de verre brisé, chez toi, si tu tentes de dépiler les verres en FIFO!

    ;D ;D
  • Philippe49Philippe49 Membre
    mai 2008 modifié #26
    Je ne trouve ni dans Ritchie, ni dans la norme C99 une règle sur l'ordre d'évaluation des arguments pour une fonction.
    Voilà  ce que dit Ritchie :
    Pour les arguments de fonctions :
    "L'ordre des évaluations des arguments n'est pas défini : notez bien qu'il varie selon le compilateur. Toutefois tous les arguments et le désignateur de fonction sont entièrement évalués, y compris leurs effets de bord, avant d'entrer dans la fonction."
    Vague donc sur le moment d'évaluation de ces dits effets de bord ... Mais il y a peut être des références plus précises depuis, ou une "jurisprudence" ... je ne demande qu'à  voir.


    Pour l'opérateur virgule, par contre c'est clair : "Tous les effets de bord de l'opérande de gauche sont effectués avant de commencer à  opérer l'opérande de droite."
  • schlumschlum Membre
    15:46 modifié #27
    Oui, ça dépend du compilateur...
    Mais que ça soit Intel ou PPC c'est dans le sens inverse si je ne m'abuse  ;)
Connectez-vous ou Inscrivez-vous pour répondre.