Vincent Lefevre a écrit :
> Tous les compilateurs ne détectent peut-être pas que le signe du "%"
> n'aura aucune influence à cause du "!".
En réalité, je ne pense pas que ce soit l'explication ultime puisque si
je supprime des return des trois fonctions la présence du symbole "!" de
négation, les écarts restent dans le même sens.
Je pense en fait que, tout simplement, si le compilateur est sûr et
certain que l'on effectue une division entre entiers d'un type non
signé (à cause de la conversion que tu suggères et des règles de
conversion), il tente une division par décalage de bits (j'ai
vérifié que cela marchait aussi pour des puissances de 2 et pas
seulement 2). D'ailleurs, si on écrit plutôt :
int est_pair2(int n)
{
return (n % 2U);
}
le temps est le même que si on faisait n & 1 ou (unsigned int) n % 2.
Vincent Lefevre a écrit :
> Tous les compilateurs ne détectent peut-être pas que le signe du "%"
> n'aura aucune influence à cause du "!".
En réalité, je ne pense pas que ce soit l'explication ultime puisque si
je supprime des return des trois fonctions la présence du symbole "!" de
négation, les écarts restent dans le même sens.
Je pense en fait que, tout simplement, si le compilateur est sûr et
certain que l'on effectue une division entre entiers d'un type non
signé (à cause de la conversion que tu suggères et des règles de
conversion), il tente une division par décalage de bits (j'ai
vérifié que cela marchait aussi pour des puissances de 2 et pas
seulement 2). D'ailleurs, si on écrit plutôt :
int est_pair2(int n)
{
return (n % 2U);
}
le temps est le même que si on faisait n & 1 ou (unsigned int) n % 2.
Vincent Lefevre a écrit :
> Tous les compilateurs ne détectent peut-être pas que le signe du "%"
> n'aura aucune influence à cause du "!".
En réalité, je ne pense pas que ce soit l'explication ultime puisque si
je supprime des return des trois fonctions la présence du symbole "!" de
négation, les écarts restent dans le même sens.
Je pense en fait que, tout simplement, si le compilateur est sûr et
certain que l'on effectue une division entre entiers d'un type non
signé (à cause de la conversion que tu suggères et des règles de
conversion), il tente une division par décalage de bits (j'ai
vérifié que cela marchait aussi pour des puissances de 2 et pas
seulement 2). D'ailleurs, si on écrit plutôt :
int est_pair2(int n)
{
return (n % 2U);
}
le temps est le même que si on faisait n & 1 ou (unsigned int) n % 2.
D'ailleurs la représentation en complément à 2 est assez dangereuse dans
le sens ou elle est "asymétrique". La valeur minimale est son propre
inverse (sommée à elle même elle le résultat vaut zéro), donc on ne peut
assumer que l'opposé d'un nombre négatif est toujours positif.
D'ailleurs la représentation en complément à 2 est assez dangereuse dans
le sens ou elle est "asymétrique". La valeur minimale est son propre
inverse (sommée à elle même elle le résultat vaut zéro), donc on ne peut
assumer que l'opposé d'un nombre négatif est toujours positif.
D'ailleurs la représentation en complément à 2 est assez dangereuse dans
le sens ou elle est "asymétrique". La valeur minimale est son propre
inverse (sommée à elle même elle le résultat vaut zéro), donc on ne peut
assumer que l'opposé d'un nombre négatif est toujours positif.
Dans l'article <4aec7ca8$0$29451$,
Samuel Devulder écrit:D'ailleurs la représentation en complément à 2 est assez dangereuse dans
le sens ou elle est "asymétrique". La valeur minimale est son propre
inverse (sommée à elle même elle le résultat vaut zéro), donc on ne peut
assumer que l'opposé d'un nombre négatif est toujours positif.
En C ISO, il y a un overflow et c'est un UB.
conforme, l'opposé d'un nombre négatif est toujours positif, et
Dans l'article <4aec7ca8$0$29451$426a34cc@news.free.fr>,
Samuel Devulder <samuel-dot-devulder@geensys.com> écrit:
D'ailleurs la représentation en complément à 2 est assez dangereuse dans
le sens ou elle est "asymétrique". La valeur minimale est son propre
inverse (sommée à elle même elle le résultat vaut zéro), donc on ne peut
assumer que l'opposé d'un nombre négatif est toujours positif.
En C ISO, il y a un overflow et c'est un UB.
conforme, l'opposé d'un nombre négatif est toujours positif, et
Dans l'article <4aec7ca8$0$29451$,
Samuel Devulder écrit:D'ailleurs la représentation en complément à 2 est assez dangereuse dans
le sens ou elle est "asymétrique". La valeur minimale est son propre
inverse (sommée à elle même elle le résultat vaut zéro), donc on ne peut
assumer que l'opposé d'un nombre négatif est toujours positif.
En C ISO, il y a un overflow et c'est un UB.
conforme, l'opposé d'un nombre négatif est toujours positif, et
Vous m'étonnez. CF plus haut. Rassurez-moi: vous êtes dans l'Education
Nationale ?
Vous m'étonnez. CF plus haut. Rassurez-moi: vous êtes dans l'Education
Nationale ?
Vous m'étonnez. CF plus haut. Rassurez-moi: vous êtes dans l'Education
Nationale ?
-ed- a écrit :
>> printf("estpair%d : %.2lf secondesnn", j, duree/N B_TESTS);
> N'existe pas. C'est
> printf("estpair%d : %.2f secondesnn", j, duree/ NB_TESTS);
Non. "%lf" est tout à fait valide, même s'il est plus courant d'écr ire "%f".
-ed- a écrit :
>> printf("estpair%d : %.2lf secondesnn", j, duree/N B_TESTS);
> N'existe pas. C'est
> printf("estpair%d : %.2f secondesnn", j, duree/ NB_TESTS);
Non. "%lf" est tout à fait valide, même s'il est plus courant d'écr ire "%f".
-ed- a écrit :
>> printf("estpair%d : %.2lf secondesnn", j, duree/N B_TESTS);
> N'existe pas. C'est
> printf("estpair%d : %.2f secondesnn", j, duree/ NB_TESTS);
Non. "%lf" est tout à fait valide, même s'il est plus courant d'écr ire "%f".
Ce que je veux dire, c'est qu'en C, les variables sont signées, et ça
fout un grosse merde.
Ce que je veux dire, c'est qu'en C, les variables sont signées, et ça
fout un grosse merde.
Ce que je veux dire, c'est qu'en C, les variables sont signées, et ça
fout un grosse merde.
Non. "%lf" est tout à fait valide, même s'il est plus courant d'écrire
"%f".
Non. "%lf" est tout à fait valide, même s'il est plus courant d'écrire
"%f".
Non. "%lf" est tout à fait valide, même s'il est plus courant d'écrire
"%f".
Oui, tu veux dire qu'en ASM on doit savoir ce que l'on fait.
En fait le soucis est que l'on ne pense pas naturellement en complément à 2.
Je suis persuadé que beaucoup, si
ce n'est tous pensent intuitivement "positif" ou éventuellement avec un
bit de signe séparé du reste comme dans les float IEEE (donc 2 valeurs
de zéro). Cela n'aide pas à écrire des expressions valides
indépendamment du signe.
Oui, tu veux dire qu'en ASM on doit savoir ce que l'on fait.
En fait le soucis est que l'on ne pense pas naturellement en complément à 2.
Je suis persuadé que beaucoup, si
ce n'est tous pensent intuitivement "positif" ou éventuellement avec un
bit de signe séparé du reste comme dans les float IEEE (donc 2 valeurs
de zéro). Cela n'aide pas à écrire des expressions valides
indépendamment du signe.
Oui, tu veux dire qu'en ASM on doit savoir ce que l'on fait.
En fait le soucis est que l'on ne pense pas naturellement en complément à 2.
Je suis persuadé que beaucoup, si
ce n'est tous pensent intuitivement "positif" ou éventuellement avec un
bit de signe séparé du reste comme dans les float IEEE (donc 2 valeurs
de zéro). Cela n'aide pas à écrire des expressions valides
indépendamment du signe.
Le truc est qu'à en croire la norme, les programmes conformes ne sont
pas légions. J'ai lu que toutes les addition signed sont un risque
d'overflow et donc d'UB d'après la norme. En revanche les overflow sur
unsigned ne font jammais d'UB et car ils "wrap" automatiquement. J'ai le
sentiment qu'on devrait le plus possible utiliser des unsigned au lieu
de int dans les progs pour ne pas risquer de soucis avec les UB de
l'arithmétique signée.
En plus du fait de l'absence d'UB, il y a des chances que l'optimiseur
fasse un meilleur job. Exemple: en théorie l'addition est associative
avec les unsigned, mais pas avec les signed car l'associativité sur les
signed risque d'introduire des UB.
Y a t'il une raison de favoriser les signed au lieu des unsigned dans
les progs? Des raisons Historique? Pratiques? (on préfère faire un
int i = ...;
while(--i>=0) {...}
plutot qu'un
unsigned i = ...;
while(i-->0) {...}
?)
Le truc est qu'à en croire la norme, les programmes conformes ne sont
pas légions. J'ai lu que toutes les addition signed sont un risque
d'overflow et donc d'UB d'après la norme. En revanche les overflow sur
unsigned ne font jammais d'UB et car ils "wrap" automatiquement. J'ai le
sentiment qu'on devrait le plus possible utiliser des unsigned au lieu
de int dans les progs pour ne pas risquer de soucis avec les UB de
l'arithmétique signée.
En plus du fait de l'absence d'UB, il y a des chances que l'optimiseur
fasse un meilleur job. Exemple: en théorie l'addition est associative
avec les unsigned, mais pas avec les signed car l'associativité sur les
signed risque d'introduire des UB.
Y a t'il une raison de favoriser les signed au lieu des unsigned dans
les progs? Des raisons Historique? Pratiques? (on préfère faire un
int i = ...;
while(--i>=0) {...}
plutot qu'un
unsigned i = ...;
while(i-->0) {...}
?)
Le truc est qu'à en croire la norme, les programmes conformes ne sont
pas légions. J'ai lu que toutes les addition signed sont un risque
d'overflow et donc d'UB d'après la norme. En revanche les overflow sur
unsigned ne font jammais d'UB et car ils "wrap" automatiquement. J'ai le
sentiment qu'on devrait le plus possible utiliser des unsigned au lieu
de int dans les progs pour ne pas risquer de soucis avec les UB de
l'arithmétique signée.
En plus du fait de l'absence d'UB, il y a des chances que l'optimiseur
fasse un meilleur job. Exemple: en théorie l'addition est associative
avec les unsigned, mais pas avec les signed car l'associativité sur les
signed risque d'introduire des UB.
Y a t'il une raison de favoriser les signed au lieu des unsigned dans
les progs? Des raisons Historique? Pratiques? (on préfère faire un
int i = ...;
while(--i>=0) {...}
plutot qu'un
unsigned i = ...;
while(i-->0) {...}
?)
Vincent Lefevre a écrit :
> Dans un programme conforme, l'opposé d'un nombre négatif est
> toujours positif, et
Le truc est qu'à en croire la norme, les programmes conformes ne sont
pas légions. J'ai lu que toutes les addition signed sont un risque
d'overflow et donc d'UB d'après la norme. En revanche les overflow sur
unsigned ne font jammais d'UB et car ils "wrap" automatiquement. J'ai le
sentiment qu'on devrait le plus possible utiliser des unsigned au lieu
de int dans les progs pour ne pas risquer de soucis avec les UB de
l'arithmétique signée.
En plus du fait de l'absence d'UB, il y a des chances que l'optimiseur
fasse un meilleur job.
Exemple: en théorie l'addition est associative avec les unsigned,
mais pas avec les signed car l'associativité sur les signed risque
d'introduire des UB.
Vincent Lefevre a écrit :
> Dans un programme conforme, l'opposé d'un nombre négatif est
> toujours positif, et
Le truc est qu'à en croire la norme, les programmes conformes ne sont
pas légions. J'ai lu que toutes les addition signed sont un risque
d'overflow et donc d'UB d'après la norme. En revanche les overflow sur
unsigned ne font jammais d'UB et car ils "wrap" automatiquement. J'ai le
sentiment qu'on devrait le plus possible utiliser des unsigned au lieu
de int dans les progs pour ne pas risquer de soucis avec les UB de
l'arithmétique signée.
En plus du fait de l'absence d'UB, il y a des chances que l'optimiseur
fasse un meilleur job.
Exemple: en théorie l'addition est associative avec les unsigned,
mais pas avec les signed car l'associativité sur les signed risque
d'introduire des UB.
Vincent Lefevre a écrit :
> Dans un programme conforme, l'opposé d'un nombre négatif est
> toujours positif, et
Le truc est qu'à en croire la norme, les programmes conformes ne sont
pas légions. J'ai lu que toutes les addition signed sont un risque
d'overflow et donc d'UB d'après la norme. En revanche les overflow sur
unsigned ne font jammais d'UB et car ils "wrap" automatiquement. J'ai le
sentiment qu'on devrait le plus possible utiliser des unsigned au lieu
de int dans les progs pour ne pas risquer de soucis avec les UB de
l'arithmétique signée.
En plus du fait de l'absence d'UB, il y a des chances que l'optimiseur
fasse un meilleur job.
Exemple: en théorie l'addition est associative avec les unsigned,
mais pas avec les signed car l'associativité sur les signed risque
d'introduire des UB.