Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Decalages d'un nombre de bits pouvant etre >= a la taille du type

134 réponses
Avatar
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"?

--
Vincent Lefèvre <vincent@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

10 réponses

1 2 3 4 5
Avatar
Fab
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"?

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / SPACES project at LORIA


Avatar
Laurent Deniau
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?

a+, ld.

Avatar
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?

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

Avatar
Vincent Lefevre
Dans l'article <41616135$0$24279$,
Fab é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).

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

Avatar
Laurent Deniau
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.

a+, ld.


Avatar
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.



Avatar
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.

}


--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / SPACES project at LORIA



Avatar
Laurent Deniau
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?

a+, ld.




Avatar
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.





Avatar
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.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

1 2 3 4 5