Decalages d'un nombre de bits pouvant etre >= a la taille du type
134 réponses
Vincent Lefevre
J'ai besoin de faire un décalage vers la droite sur un type entier
(disons non signé) générique (i.e. défini par typedef) d'un certain
nombre constant de bits. Le problème est que ce nombre de bits peut
être supérieur ou égal à la taille du type en question. Une idée
sur la façon de faire ça efficacement sans obtenir de comportement
indéfini et sans passer par un outil du style "configure"?
euh, une question au passage, quel est l'interet de deplacer plus de bit que n'en contient la variable, on perd toute l'information non?
"Vincent Lefevre" <vincent+ schrieb im Newsbeitrag news:20041004141107$
J'ai besoin de faire un décalage vers la droite sur un type entier (disons non signé) générique (i.e. défini par typedef) d'un certain nombre constant de bits. Le problème est que ce nombre de bits peut être supérieur ou égal à la taille du type en question. Une idée sur la façon de faire ça efficacement sans obtenir de comportement indéfini et sans passer par un outil du style "configure"?
euh, une question au passage, quel est l'interet de deplacer plus de bit que
n'en contient la variable, on perd toute l'information non?
"Vincent Lefevre" <vincent+news@vinc17.org> schrieb im Newsbeitrag
news:20041004141107$69dc@vinc17.org...
J'ai besoin de faire un décalage vers la droite sur un type entier
(disons non signé) générique (i.e. défini par typedef) d'un certain
nombre constant de bits. Le problème est que ce nombre de bits peut
être supérieur ou égal à la taille du type en question. Une idée
sur la façon de faire ça efficacement sans obtenir de comportement
indéfini et sans passer par un outil du style "configure"?
euh, une question au passage, quel est l'interet de deplacer plus de bit que n'en contient la variable, on perd toute l'information non?
"Vincent Lefevre" <vincent+ schrieb im Newsbeitrag news:20041004141107$
J'ai besoin de faire un décalage vers la droite sur un type entier (disons non signé) générique (i.e. défini par typedef) d'un certain nombre constant de bits. Le problème est que ce nombre de bits peut être supérieur ou égal à la taille du type en question. Une idée sur la façon de faire ça efficacement sans obtenir de comportement indéfini et sans passer par un outil du style "configure"?
J'ai besoin de faire un décalage vers la droite sur un type entier (disons non signé) générique (i.e. défini par typedef) d'un certain nombre constant de bits. Le problème est que ce nombre de bits peut être supérieur ou égal à la taille du type en question. Une idée sur la façon de faire ça efficacement sans obtenir de comportement indéfini et sans passer par un outil du style "configure"?
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
a+, ld.
Vincent Lefevre wrote:
J'ai besoin de faire un décalage vers la droite sur un type entier
(disons non signé) générique (i.e. défini par typedef) d'un certain
nombre constant de bits. Le problème est que ce nombre de bits peut
être supérieur ou égal à la taille du type en question. Une idée
sur la façon de faire ça efficacement sans obtenir de comportement
indéfini et sans passer par un outil du style "configure"?
a quel point efficace? en faisant un cast sur un unsigned long serait
trop lent?
J'ai besoin de faire un décalage vers la droite sur un type entier (disons non signé) générique (i.e. défini par typedef) d'un certain nombre constant de bits. Le problème est que ce nombre de bits peut être supérieur ou égal à la taille du type en question. Une idée sur la façon de faire ça efficacement sans obtenir de comportement indéfini et sans passer par un outil du style "configure"?
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
a+, ld.
Vincent Lefevre
Dans l'article <cjrnsn$bii$, Laurent Deniau écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
En quoi un cast en unsigned long changerait quelque chose?
euh, une question au passage, quel est l'interet de deplacer plus de bit que n'en contient la variable, on perd toute l'information non?
Oui, on perd toute l'information. Mais je ne le sais pas à l'avance (sur certaines archi, on perd tout, sur d'autres non). Si tu veux un exemple, voici un bout de code temporaire:
#define R_MULI(d,a,b) do { int I = 0; index_t T = b; mpn_mul_1 (d, a, ARITH_MPN, (mp_limb_t) T); if ((index_t) -1 > (mp_limb_t) -1) while ((T >>= GMP_LIMB_BITS) && ARITH_MPN - ++I > 0) mpn_addmul_1 (d + I, a, ARITH_MPN - I, (mp_limb_t) T); } while (0)
ARITH_MPN contient une taille: 2, 3, 4... et d et a sont des pointeurs vers des tableaux de mp_limb_t (il s'agit de la couche MPN de GMP). Le problème est le décalage de GMP_LIMB_BITS bits, même s'il n'est jamais exécuté en dynamique dans les cas où ça pose problème (d'ailleurs, gcc se plaint).
Dans l'article <41616135$0$24279$626a14ce@news.free.fr>,
Fab <fuckyduck@free.fr> écrit:
euh, une question au passage, quel est l'interet de deplacer plus de
bit que n'en contient la variable, on perd toute l'information non?
Oui, on perd toute l'information. Mais je ne le sais pas à l'avance
(sur certaines archi, on perd tout, sur d'autres non). Si tu veux un
exemple, voici un bout de code temporaire:
#define R_MULI(d,a,b)
do
{
int I = 0;
index_t T = b;
mpn_mul_1 (d, a, ARITH_MPN, (mp_limb_t) T);
if ((index_t) -1 > (mp_limb_t) -1)
while ((T >>= GMP_LIMB_BITS) && ARITH_MPN - ++I > 0)
mpn_addmul_1 (d + I, a, ARITH_MPN - I, (mp_limb_t) T);
}
while (0)
ARITH_MPN contient une taille: 2, 3, 4... et d et a sont des pointeurs
vers des tableaux de mp_limb_t (il s'agit de la couche MPN de GMP). Le
problème est le décalage de GMP_LIMB_BITS bits, même s'il n'est jamais
exécuté en dynamique dans les cas où ça pose problème (d'ailleurs, gcc
se plaint).
euh, une question au passage, quel est l'interet de deplacer plus de bit que n'en contient la variable, on perd toute l'information non?
Oui, on perd toute l'information. Mais je ne le sais pas à l'avance (sur certaines archi, on perd tout, sur d'autres non). Si tu veux un exemple, voici un bout de code temporaire:
#define R_MULI(d,a,b) do { int I = 0; index_t T = b; mpn_mul_1 (d, a, ARITH_MPN, (mp_limb_t) T); if ((index_t) -1 > (mp_limb_t) -1) while ((T >>= GMP_LIMB_BITS) && ARITH_MPN - ++I > 0) mpn_addmul_1 (d + I, a, ARITH_MPN - I, (mp_limb_t) T); } while (0)
ARITH_MPN contient une taille: 2, 3, 4... et d et a sont des pointeurs vers des tableaux de mp_limb_t (il s'agit de la couche MPN de GMP). Le problème est le décalage de GMP_LIMB_BITS bits, même s'il n'est jamais exécuté en dynamique dans les cas où ça pose problème (d'ailleurs, gcc se plaint).
Dans l'article <cjrnsn$bii$, Laurent Deniau écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et donc tu peux verifier si le comportement est indefini.
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) { U >>= GMP_LIMB_BITS / 2; U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2; } else { U >>= GMP_LIMB_BITS; }
T = U;
Si comme je le suppose GMP_LIMB_BITS est une constante, tout cela est simplifie a la compilation a un ou deux shifts sur T. Tu peux aussi rajouter des cas pour 64 et 128 bits le cas echeant mais il faut alors utiliser les directives du compilateur.
a+, ld.
Vincent Lefevre wrote:
Dans l'article <cjrnsn$bii$1@sunnews.cern.ch>,
Laurent Deniau <Laurent.Deniau@cern.ch> écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait
trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et
donc tu peux verifier si le comportement est indefini.
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) {
U >>= GMP_LIMB_BITS / 2;
U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2;
} else {
U >>= GMP_LIMB_BITS;
}
T = U;
Si comme je le suppose GMP_LIMB_BITS est une constante, tout cela est
simplifie a la compilation a un ou deux shifts sur T. Tu peux aussi
rajouter des cas pour 64 et 128 bits le cas echeant mais il faut alors
utiliser les directives du compilateur.
Dans l'article <cjrnsn$bii$, Laurent Deniau écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et donc tu peux verifier si le comportement est indefini.
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) { U >>= GMP_LIMB_BITS / 2; U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2; } else { U >>= GMP_LIMB_BITS; }
T = U;
Si comme je le suppose GMP_LIMB_BITS est une constante, tout cela est simplifie a la compilation a un ou deux shifts sur T. Tu peux aussi rajouter des cas pour 64 et 128 bits le cas echeant mais il faut alors utiliser les directives du compilateur.
a+, ld.
Laurent Deniau
Laurent Deniau wrote:
Vincent Lefevre wrote:
Dans l'article <cjrnsn$bii$, Laurent Deniau écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et donc tu peux verifier si le comportement est indefini.
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) { U >>= GMP_LIMB_BITS / 2; U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2; } else { U >>= GMP_LIMB_BITS; }
T = U;
Si comme je le suppose GMP_LIMB_BITS est une constante, tout cela est simplifie a la compilation a un ou deux shifts sur T. Tu peux aussi rajouter des cas pour 64 et 128 bits le cas echeant mais il faut alors utiliser les directives du compilateur.
oups, je voulais dire du preprocesseur.
a+, ld.
Laurent Deniau wrote:
Vincent Lefevre wrote:
Dans l'article <cjrnsn$bii$1@sunnews.cern.ch>,
Laurent Deniau <Laurent.Deniau@cern.ch> écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait
trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et
donc tu peux verifier si le comportement est indefini.
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) {
U >>= GMP_LIMB_BITS / 2;
U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2;
} else {
U >>= GMP_LIMB_BITS;
}
T = U;
Si comme je le suppose GMP_LIMB_BITS est une constante, tout cela est
simplifie a la compilation a un ou deux shifts sur T. Tu peux aussi
rajouter des cas pour 64 et 128 bits le cas echeant mais il faut alors
utiliser les directives du compilateur.
Dans l'article <cjrnsn$bii$, Laurent Deniau écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et donc tu peux verifier si le comportement est indefini.
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) { U >>= GMP_LIMB_BITS / 2; U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2; } else { U >>= GMP_LIMB_BITS; }
T = U;
Si comme je le suppose GMP_LIMB_BITS est une constante, tout cela est simplifie a la compilation a un ou deux shifts sur T. Tu peux aussi rajouter des cas pour 64 et 128 bits le cas echeant mais il faut alors utiliser les directives du compilateur.
oups, je voulais dire du preprocesseur.
a+, ld.
Vincent Lefevre
Dans l'article <cjtojf$6j0$, Laurent Deniau écrit:
Vincent Lefevre wrote:
Dans l'article <cjrnsn$bii$, Laurent Deniau écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et donc tu peux verifier si le comportement est indefini.
Le cast en lui-même n'est pas inefficace, mais le fait de travailler sur un type plus petit (sur machine 64 bits par exemple), oui. Et ça ne résout rien...
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) { U >>= GMP_LIMB_BITS / 2; U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2; } else { U >>= GMP_LIMB_BITS;
Là il y a comportement indéfini si GMP_LIMB_BITS = 64.
Dans l'article <cjtojf$6j0$1@sunnews.cern.ch>,
Laurent Deniau <Laurent.Deniau@cern.ch> écrit:
Vincent Lefevre wrote:
Dans l'article <cjrnsn$bii$1@sunnews.cern.ch>,
Laurent Deniau <Laurent.Deniau@cern.ch> écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait
trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et
donc tu peux verifier si le comportement est indefini.
Le cast en lui-même n'est pas inefficace, mais le fait de travailler
sur un type plus petit (sur machine 64 bits par exemple), oui. Et ça
ne résout rien...
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) {
U >>= GMP_LIMB_BITS / 2;
U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2;
} else {
U >>= GMP_LIMB_BITS;
Là il y a comportement indéfini si GMP_LIMB_BITS = 64.
Dans l'article <cjtojf$6j0$, Laurent Deniau écrit:
Vincent Lefevre wrote:
Dans l'article <cjrnsn$bii$, Laurent Deniau écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et donc tu peux verifier si le comportement est indefini.
Le cast en lui-même n'est pas inefficace, mais le fait de travailler sur un type plus petit (sur machine 64 bits par exemple), oui. Et ça ne résout rien...
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) { U >>= GMP_LIMB_BITS / 2; U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2; } else { U >>= GMP_LIMB_BITS;
Là il y a comportement indéfini si GMP_LIMB_BITS = 64.
Dans l'article <cjtojf$6j0$, Laurent Deniau écrit:
Vincent Lefevre wrote:
Dans l'article <cjrnsn$bii$, Laurent Deniau écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et donc tu peux verifier si le comportement est indefini.
Le cast en lui-même n'est pas inefficace, mais le fait de travailler sur un type plus petit (sur machine 64 bits par exemple), oui. Et ça ne résout rien...
Si.
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) { U >>= GMP_LIMB_BITS / 2; U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2; } else { U >>= GMP_LIMB_BITS;
Là il y a comportement indéfini si GMP_LIMB_BITS = 64.
As-tu lu mon post jusqu'au bout?
a+, ld.
Vincent Lefevre wrote:
Dans l'article <cjtojf$6j0$1@sunnews.cern.ch>,
Laurent Deniau <Laurent.Deniau@cern.ch> écrit:
Vincent Lefevre wrote:
Dans l'article <cjrnsn$bii$1@sunnews.cern.ch>,
Laurent Deniau <Laurent.Deniau@cern.ch> écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait
trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et
donc tu peux verifier si le comportement est indefini.
Le cast en lui-même n'est pas inefficace, mais le fait de travailler
sur un type plus petit (sur machine 64 bits par exemple), oui. Et ça
ne résout rien...
Si.
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) {
U >>= GMP_LIMB_BITS / 2;
U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2;
} else {
U >>= GMP_LIMB_BITS;
Là il y a comportement indéfini si GMP_LIMB_BITS = 64.
Dans l'article <cjtojf$6j0$, Laurent Deniau écrit:
Vincent Lefevre wrote:
Dans l'article <cjrnsn$bii$, Laurent Deniau écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et donc tu peux verifier si le comportement est indefini.
Le cast en lui-même n'est pas inefficace, mais le fait de travailler sur un type plus petit (sur machine 64 bits par exemple), oui. Et ça ne résout rien...
Si.
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) { U >>= GMP_LIMB_BITS / 2; U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2; } else { U >>= GMP_LIMB_BITS;
Là il y a comportement indéfini si GMP_LIMB_BITS = 64.
As-tu lu mon post jusqu'au bout?
a+, ld.
Laurent Deniau
Laurent Deniau wrote:
Vincent Lefevre wrote:
Dans l'article <cjtojf$6j0$, Laurent Deniau écrit:
Vincent Lefevre wrote:
Dans l'article <cjrnsn$bii$, Laurent Deniau écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et donc tu peux verifier si le comportement est indefini.
Le cast en lui-même n'est pas inefficace, mais le fait de travailler sur un type plus petit (sur machine 64 bits par exemple), oui. Et ça ne résout rien...
Si.
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) { U >>= GMP_LIMB_BITS / 2; U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2; } else { U >>= GMP_LIMB_BITS;
Là il y a comportement indéfini si GMP_LIMB_BITS = 64.
As-tu lu mon post jusqu'au bout?
Au passage, tu ne nous as toujours pas explique pourquoi tu tiens absolument a faire les decalages?
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) { U = 0; } else { U >>= GMP_LIMB_BITS; }
T = U
est quand meme plus simple et defini.
a+, ld.
Laurent Deniau wrote:
Vincent Lefevre wrote:
Dans l'article <cjtojf$6j0$1@sunnews.cern.ch>,
Laurent Deniau <Laurent.Deniau@cern.ch> écrit:
Vincent Lefevre wrote:
Dans l'article <cjrnsn$bii$1@sunnews.cern.ch>,
Laurent Deniau <Laurent.Deniau@cern.ch> écrit:
a quel point efficace? en faisant un cast sur un unsigned long
serait trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et
donc tu peux verifier si le comportement est indefini.
Le cast en lui-même n'est pas inefficace, mais le fait de travailler
sur un type plus petit (sur machine 64 bits par exemple), oui. Et ça
ne résout rien...
Si.
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) {
U >>= GMP_LIMB_BITS / 2;
U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2;
} else {
U >>= GMP_LIMB_BITS;
Là il y a comportement indéfini si GMP_LIMB_BITS = 64.
As-tu lu mon post jusqu'au bout?
Au passage, tu ne nous as toujours pas explique pourquoi tu tiens
absolument a faire les decalages?
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) {
U = 0;
} else {
U >>= GMP_LIMB_BITS;
}
Dans l'article <cjtojf$6j0$, Laurent Deniau écrit:
Vincent Lefevre wrote:
Dans l'article <cjrnsn$bii$, Laurent Deniau écrit:
a quel point efficace? en faisant un cast sur un unsigned long serait trop lent?
En quoi un cast en unsigned long changerait quelque chose?
Parce que dans ce cas tu connais le type sur lequel tu travailles et donc tu peux verifier si le comportement est indefini.
Le cast en lui-même n'est pas inefficace, mais le fait de travailler sur un type plus petit (sur machine 64 bits par exemple), oui. Et ça ne résout rien...
Si.
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) { U >>= GMP_LIMB_BITS / 2; U >>= GMP_LIMB_BITS - GMP_LIMB_BITS / 2; } else { U >>= GMP_LIMB_BITS;
Là il y a comportement indéfini si GMP_LIMB_BITS = 64.
As-tu lu mon post jusqu'au bout?
Au passage, tu ne nous as toujours pas explique pourquoi tu tiens absolument a faire les decalages?
unsigned long U = T;
if (ULONG_MAX == 4294967295UL && GMP_LIMB_BITS > 31) { U = 0; } else { U >>= GMP_LIMB_BITS; }
T = U
est quand meme plus simple et defini.
a+, ld.
Vincent Lefevre
Dans l'article <cju88c$d81$, Laurent Deniau écrit:
As-tu lu mon post jusqu'au bout?
J'ai dû mal comprendre ton post alors. Donc si tu sous-entends qu'il faut rajouter du code à chaque fois qu'on a une taille différente (et encore, je ne vois pas en quoi cela résout le problème), ce n'est pas une bonne solution. Je veux quelque chose de 100% portable.
Dans l'article <cju88c$d81$1@sunnews.cern.ch>,
Laurent Deniau <Laurent.Deniau@cern.ch> écrit:
As-tu lu mon post jusqu'au bout?
J'ai dû mal comprendre ton post alors. Donc si tu sous-entends
qu'il faut rajouter du code à chaque fois qu'on a une taille
différente (et encore, je ne vois pas en quoi cela résout le
problème), ce n'est pas une bonne solution. Je veux quelque
chose de 100% portable.
Dans l'article <cju88c$d81$, Laurent Deniau écrit:
As-tu lu mon post jusqu'au bout?
J'ai dû mal comprendre ton post alors. Donc si tu sous-entends qu'il faut rajouter du code à chaque fois qu'on a une taille différente (et encore, je ne vois pas en quoi cela résout le problème), ce n'est pas une bonne solution. Je veux quelque chose de 100% portable.