Pierre Maurette wrote in message
news:...
[...]N est une constante, apparemment, ainsi que P pendant le
calcul. Votre problème esr ainsi simplifié :
int resultat = (k*N)/P; //c'est tout
ou même
int resultat = (k<<8)/P;
Jamais. Il veut multiplier, non décaler.
Surtout que je déclare resultat en int (et non unsigned int). Laisser
faire le compilateur, en déclarant toutefois N const si c'est le cas.
Question subsidiaire: (je me situe pour l'exemple dans une
architecture où la multiplication serait très pénalisante par rapport
au décalage). Si N est constant dans une boucle, faut-il faire
confiance au compilateur ou est-il préférable de l'orienter par un
cast ou autre méthode ? Si oui, laquelle (en C et en C++) ?
Je ne sais pas exactement ce que tu veux dire par « constant dans une
boucle ». S'il ne s'agit pas d'une constante au moment de la
compilation, il n'y a pas grand chose que ni toi ni le compilateur peut
faire. Et si N est une constante au moment de la compilation, c'est
égale où il est déclaré -- pour le compilateur, une constante est une
constante.
OK. Je m'étais un peu emballé. En fait, si N prend une série de
Pierre Maurette <maurette.pierre@free.fr> wrote in message
news:<2p46b0580thhfc7tinriusdssegt461uup@4ax.com>...
[...]
N est une constante, apparemment, ainsi que P pendant le
calcul. Votre problème esr ainsi simplifié :
int resultat = (k*N)/P; //c'est tout
ou même
int resultat = (k<<8)/P;
Jamais. Il veut multiplier, non décaler.
Surtout que je déclare resultat en int (et non unsigned int). Laisser
faire le compilateur, en déclarant toutefois N const si c'est le cas.
Question subsidiaire: (je me situe pour l'exemple dans une
architecture où la multiplication serait très pénalisante par rapport
au décalage). Si N est constant dans une boucle, faut-il faire
confiance au compilateur ou est-il préférable de l'orienter par un
cast ou autre méthode ? Si oui, laquelle (en C et en C++) ?
Je ne sais pas exactement ce que tu veux dire par « constant dans une
boucle ». S'il ne s'agit pas d'une constante au moment de la
compilation, il n'y a pas grand chose que ni toi ni le compilateur peut
faire. Et si N est une constante au moment de la compilation, c'est
égale où il est déclaré -- pour le compilateur, une constante est une
constante.
OK. Je m'étais un peu emballé. En fait, si N prend une série de
Pierre Maurette wrote in message
news:...
[...]N est une constante, apparemment, ainsi que P pendant le
calcul. Votre problème esr ainsi simplifié :
int resultat = (k*N)/P; //c'est tout
ou même
int resultat = (k<<8)/P;
Jamais. Il veut multiplier, non décaler.
Surtout que je déclare resultat en int (et non unsigned int). Laisser
faire le compilateur, en déclarant toutefois N const si c'est le cas.
Question subsidiaire: (je me situe pour l'exemple dans une
architecture où la multiplication serait très pénalisante par rapport
au décalage). Si N est constant dans une boucle, faut-il faire
confiance au compilateur ou est-il préférable de l'orienter par un
cast ou autre méthode ? Si oui, laquelle (en C et en C++) ?
Je ne sais pas exactement ce que tu veux dire par « constant dans une
boucle ». S'il ne s'agit pas d'une constante au moment de la
compilation, il n'y a pas grand chose que ni toi ni le compilateur peut
faire. Et si N est une constante au moment de la compilation, c'est
égale où il est déclaré -- pour le compilateur, une constante est une
constante.
OK. Je m'étais un peu emballé. En fait, si N prend une série de
Malheureusement, C/C++ n'a pas des types à sous-étendu (subrange
types). On peut les implémenter au moyens des classes, mais le résultat
est assez lourd. Alors, en général, on s'en passe. (Peut-être à tort, je
ne sais pas. Un template Subrange< typename T, T, T > ne doit pas poser
de grands problèmes.)
Peut-être y a-t-il un problème de livre et/ou d'enseignement à vouloir
Malheureusement, C/C++ n'a pas des types à sous-étendu (subrange
types). On peut les implémenter au moyens des classes, mais le résultat
est assez lourd. Alors, en général, on s'en passe. (Peut-être à tort, je
ne sais pas. Un template Subrange< typename T, T, T > ne doit pas poser
de grands problèmes.)
Peut-être y a-t-il un problème de livre et/ou d'enseignement à vouloir
Malheureusement, C/C++ n'a pas des types à sous-étendu (subrange
types). On peut les implémenter au moyens des classes, mais le résultat
est assez lourd. Alors, en général, on s'en passe. (Peut-être à tort, je
ne sais pas. Un template Subrange< typename T, T, T > ne doit pas poser
de grands problèmes.)
Peut-être y a-t-il un problème de livre et/ou d'enseignement à vouloir
Pierre Maurette wrote in message
news:...Je vous laisse, par rapport à ce que vous souhaitez, juger de
l'oportunité d'un ajustement par floor(). Personnellement, je ne
l'utiliserais pas, puisque c'est une fonction double.
Si les valeurs sont signées, il a intérêt à passer en flottant de toute
façon. La division avec des résultats négatifs n'est pas bien définie en
C++.
Pierre Maurette <maurette.pierre@free.fr> wrote in message
news:<cat3b05qmcpdous2n731hvsfu9lobbqskq@4ax.com>...
Je vous laisse, par rapport à ce que vous souhaitez, juger de
l'oportunité d'un ajustement par floor(). Personnellement, je ne
l'utiliserais pas, puisque c'est une fonction double.
Si les valeurs sont signées, il a intérêt à passer en flottant de toute
façon. La division avec des résultats négatifs n'est pas bien définie en
C++.
Pierre Maurette wrote in message
news:...Je vous laisse, par rapport à ce que vous souhaitez, juger de
l'oportunité d'un ajustement par floor(). Personnellement, je ne
l'utiliserais pas, puisque c'est une fonction double.
Si les valeurs sont signées, il a intérêt à passer en flottant de toute
façon. La division avec des résultats négatifs n'est pas bien définie en
C++.
le Tuesday 25 May 2004 23:38, écrivit :Pour les classes on conseille de s'inspirer de "l'univers du problème" ;
serait-ce une tare de faire de même pour d'autres types, encore
plus basiques ? Quand une variable représente un entier qui n'a
aucun sens autre que positif, cela me révulse absolument qu'il
ne soit pas unsigned.
en cherchant un exple, il me vient :
for(unsigned int n = 25; n>= 0; --n) ;
c'est pour moi une illustration assez simple du fait que les unsigned int
sont mal adaptés pour modéliser un sous ensemble des nombres entiers
positifs.
Dans le monde des unsigned int, "être positif" n'a pas de sens.
le Tuesday 25 May 2004 23:38, anaigeon@free.fr écrivit :
Pour les classes on conseille de s'inspirer de "l'univers du problème" ;
serait-ce une tare de faire de même pour d'autres types, encore
plus basiques ? Quand une variable représente un entier qui n'a
aucun sens autre que positif, cela me révulse absolument qu'il
ne soit pas unsigned.
en cherchant un exple, il me vient :
for(unsigned int n = 25; n>= 0; --n) ;
c'est pour moi une illustration assez simple du fait que les unsigned int
sont mal adaptés pour modéliser un sous ensemble des nombres entiers
positifs.
Dans le monde des unsigned int, "être positif" n'a pas de sens.
le Tuesday 25 May 2004 23:38, écrivit :Pour les classes on conseille de s'inspirer de "l'univers du problème" ;
serait-ce une tare de faire de même pour d'autres types, encore
plus basiques ? Quand une variable représente un entier qui n'a
aucun sens autre que positif, cela me révulse absolument qu'il
ne soit pas unsigned.
en cherchant un exple, il me vient :
for(unsigned int n = 25; n>= 0; --n) ;
c'est pour moi une illustration assez simple du fait que les unsigned int
sont mal adaptés pour modéliser un sous ensemble des nombres entiers
positifs.
Dans le monde des unsigned int, "être positif" n'a pas de sens.
Le problème, c'est ce qu'on entend par « division ». Si tu
démandes à un non-informaticien quelle est la valeur de 1/3, il
va te dire un tiers. Et non 0. Dans la mésure où l'opérateur ne
Le problème, c'est ce qu'on entend par « division ». Si tu
démandes à un non-informaticien quelle est la valeur de 1/3, il
va te dire un tiers. Et non 0. Dans la mésure où l'opérateur ne
Le problème, c'est ce qu'on entend par « division ». Si tu
démandes à un non-informaticien quelle est la valeur de 1/3, il
va te dire un tiers. Et non 0. Dans la mésure où l'opérateur ne
"Michel Michaud" wrote in message
news:<0_Jsc.27867$...Dans news:,Pierre Maurette wrote in message
news:...Mais bon, personnellement, je trouve regrettable l'utilisation de /
pour la division entière, j'aime bien le couple div mod du Pascal.
Tout à fait d'accord. Mais C/C++ ne sont pas seuls dans leur choix.
Tiens vous êtes bizarres : au contraire, j'ai toujours trouvé que les
langages où les opérations classiques (+-*/) sont dans le type des
données SAUF la division étaient plutôt bizarres. Il me semble que,
la plupart du temps, si on a des entiers pour les calculs, on veut un
entier comme résultat et la division réelle ne fait qu'apporter des
conversions inutiles.
Le problème, c'est ce qu'on entend par « division ». Si tu démandes à un
non-informaticien quelle est la valeur de 1/3, il va te dire un
tiers. Et non 0. Dans la mésure où l'opérateur ne donne pas 1/3, ou
quelque chose de proche, pour 1/3, je ne trouve pas que l'opérateur /
est bien choisi.
"Michel Michaud" <mm@gdzid.com> wrote in message
news:<0_Jsc.27867$tb4.960883@news20.bellglobal.com>...
Dans news:d6652001.0405242305.6929a8fb@posting.google.com,
Pierre Maurette <maurette.pierre@free.fr> wrote in message
news:<cat3b05qmcpdous2n731hvsfu9lobbqskq@4ax.com>...
Mais bon, personnellement, je trouve regrettable l'utilisation de /
pour la division entière, j'aime bien le couple div mod du Pascal.
Tout à fait d'accord. Mais C/C++ ne sont pas seuls dans leur choix.
Tiens vous êtes bizarres : au contraire, j'ai toujours trouvé que les
langages où les opérations classiques (+-*/) sont dans le type des
données SAUF la division étaient plutôt bizarres. Il me semble que,
la plupart du temps, si on a des entiers pour les calculs, on veut un
entier comme résultat et la division réelle ne fait qu'apporter des
conversions inutiles.
Le problème, c'est ce qu'on entend par « division ». Si tu démandes à un
non-informaticien quelle est la valeur de 1/3, il va te dire un
tiers. Et non 0. Dans la mésure où l'opérateur ne donne pas 1/3, ou
quelque chose de proche, pour 1/3, je ne trouve pas que l'opérateur /
est bien choisi.
"Michel Michaud" wrote in message
news:<0_Jsc.27867$...Dans news:,Pierre Maurette wrote in message
news:...Mais bon, personnellement, je trouve regrettable l'utilisation de /
pour la division entière, j'aime bien le couple div mod du Pascal.
Tout à fait d'accord. Mais C/C++ ne sont pas seuls dans leur choix.
Tiens vous êtes bizarres : au contraire, j'ai toujours trouvé que les
langages où les opérations classiques (+-*/) sont dans le type des
données SAUF la division étaient plutôt bizarres. Il me semble que,
la plupart du temps, si on a des entiers pour les calculs, on veut un
entier comme résultat et la division réelle ne fait qu'apporter des
conversions inutiles.
Le problème, c'est ce qu'on entend par « division ». Si tu démandes à un
non-informaticien quelle est la valeur de 1/3, il va te dire un
tiers. Et non 0. Dans la mésure où l'opérateur ne donne pas 1/3, ou
quelque chose de proche, pour 1/3, je ne trouve pas que l'opérateur /
est bien choisi.
"Michel Michaud" wrote in message
news:<EJJsc.27786$...C'est à peu près ce que je pense aussi, mais les nombreuses
discussions (sur clc++m par exemple) montrent bien que ce n'est
pas complètement noir ou blanc. En particulier, le fait que la
bibliothèque standard regorge de unsigned (pour aucune des
raisons citées plus haut) indique qu'au moins quelques grands
experts ont, pendant un certain temps, pensé autrement.
Ou que la bibliothèque n'est pas le produit des grands
experts:-).
Sérieusement, au moins dans la partie STL (et c'est bien là où on
trouve l'introduction des size_t au bout de bras), c'est bien la
troisième motivation ci-dessus qui a joué, au moins en partie.
[... i.e. un bit de plus ...]
N'oublie pas que Stepanov a beaucoup développé sur un PC, à un
époque où les PC étaient des machines à 16 bits (mais que les
pointeurs avec 32 bits). Vouloir un vector<char> avec 40000
caractères (quand on peut avoir jusqu'à 640 Ko de mémoire totale)
n'est pas si étrange que ça.
Ceci dit, je crois que c'est un « erreur » qui est du même
niveau que les conversions implicites à perte de valeur :
Pas du tout. Les conversions implicites à perte de valeur est une
erreur de conception pûre et simple. Stroustrup n'avait pas le
choix, à cause de la compatibilité C. En fait, je crois que l'
« erreur » vient du fait que C dérivait au départ de B, qui lui
n'avait pas de types du tout (et donc, pas de conversions). Mais
le fait qu'il y a une excuse ne veut pas dire que ce n'est pas
une erreur.
Moi aussi, je préfère ne pas avoir des avertissements. Mais
parfois, il y a des compilateurs qui en émettent des vraiments
bêtes.
"Michel Michaud" <mm@gdzid.com> wrote in message
news:<EJJsc.27786$tb4.956273@news20.bellglobal.com>...
C'est à peu près ce que je pense aussi, mais les nombreuses
discussions (sur clc++m par exemple) montrent bien que ce n'est
pas complètement noir ou blanc. En particulier, le fait que la
bibliothèque standard regorge de unsigned (pour aucune des
raisons citées plus haut) indique qu'au moins quelques grands
experts ont, pendant un certain temps, pensé autrement.
Ou que la bibliothèque n'est pas le produit des grands
experts:-).
Sérieusement, au moins dans la partie STL (et c'est bien là où on
trouve l'introduction des size_t au bout de bras), c'est bien la
troisième motivation ci-dessus qui a joué, au moins en partie.
[... i.e. un bit de plus ...]
N'oublie pas que Stepanov a beaucoup développé sur un PC, à un
époque où les PC étaient des machines à 16 bits (mais que les
pointeurs avec 32 bits). Vouloir un vector<char> avec 40000
caractères (quand on peut avoir jusqu'à 640 Ko de mémoire totale)
n'est pas si étrange que ça.
Ceci dit, je crois que c'est un « erreur » qui est du même
niveau que les conversions implicites à perte de valeur :
Pas du tout. Les conversions implicites à perte de valeur est une
erreur de conception pûre et simple. Stroustrup n'avait pas le
choix, à cause de la compatibilité C. En fait, je crois que l'
« erreur » vient du fait que C dérivait au départ de B, qui lui
n'avait pas de types du tout (et donc, pas de conversions). Mais
le fait qu'il y a une excuse ne veut pas dire que ce n'est pas
une erreur.
Moi aussi, je préfère ne pas avoir des avertissements. Mais
parfois, il y a des compilateurs qui en émettent des vraiments
bêtes.
"Michel Michaud" wrote in message
news:<EJJsc.27786$...C'est à peu près ce que je pense aussi, mais les nombreuses
discussions (sur clc++m par exemple) montrent bien que ce n'est
pas complètement noir ou blanc. En particulier, le fait que la
bibliothèque standard regorge de unsigned (pour aucune des
raisons citées plus haut) indique qu'au moins quelques grands
experts ont, pendant un certain temps, pensé autrement.
Ou que la bibliothèque n'est pas le produit des grands
experts:-).
Sérieusement, au moins dans la partie STL (et c'est bien là où on
trouve l'introduction des size_t au bout de bras), c'est bien la
troisième motivation ci-dessus qui a joué, au moins en partie.
[... i.e. un bit de plus ...]
N'oublie pas que Stepanov a beaucoup développé sur un PC, à un
époque où les PC étaient des machines à 16 bits (mais que les
pointeurs avec 32 bits). Vouloir un vector<char> avec 40000
caractères (quand on peut avoir jusqu'à 640 Ko de mémoire totale)
n'est pas si étrange que ça.
Ceci dit, je crois que c'est un « erreur » qui est du même
niveau que les conversions implicites à perte de valeur :
Pas du tout. Les conversions implicites à perte de valeur est une
erreur de conception pûre et simple. Stroustrup n'avait pas le
choix, à cause de la compatibilité C. En fait, je crois que l'
« erreur » vient du fait que C dérivait au départ de B, qui lui
n'avait pas de types du tout (et donc, pas de conversions). Mais
le fait qu'il y a une excuse ne veut pas dire que ce n'est pas
une erreur.
Moi aussi, je préfère ne pas avoir des avertissements. Mais
parfois, il y a des compilateurs qui en émettent des vraiments
bêtes.
Tu veux dire que ça te révulse qu'il puisse représenter les valeurs en
dehors du domaine. Moi aussi. Par exemple, si je veux un type qui
représente un dé, je ne veux pas non plus qu'il puisse représenter un 0,
ou un 100.
Malheureusement, C/C++ n'a pas des types à sous-étendu (subrange
types).
Tu veux dire que ça te révulse qu'il puisse représenter les valeurs en
dehors du domaine. Moi aussi. Par exemple, si je veux un type qui
représente un dé, je ne veux pas non plus qu'il puisse représenter un 0,
ou un 100.
Malheureusement, C/C++ n'a pas des types à sous-étendu (subrange
types).
Tu veux dire que ça te révulse qu'il puisse représenter les valeurs en
dehors du domaine. Moi aussi. Par exemple, si je veux un type qui
représente un dé, je ne veux pas non plus qu'il puisse représenter un 0,
ou un 100.
Malheureusement, C/C++ n'a pas des types à sous-étendu (subrange
types).