OVH Cloud OVH Cloud

MAXINT

4 réponses
Avatar
cbergadler
Salut,

j'aimerais trouver une méthode stable pour déterminer la valeur
maximale d'un type intégral signé ou non.

on m'a conseillé :

typedef signed char integer; // ou autre...

integer a=0-1,max=0,zero=0;

while(a<zero) // si le type est signé, tant que la valeur est négative
{
max=a;
a*=2; // ou a+=a, on décale dans le "bon sens" jusqu'au
dépassement
}
max=~zero-max; // la valeur de a est positive, on prend le complément
de 0 (11111111...) moins plus petite valeur négative représentable
dans max (0 si unsigned)

max contient alors valeur maximale d'integer (127 sur mon système)
mais j'espère qu'on peut faire mieux et je ne sais pas si c'est
"convenablement" protable (disons sur des architectures bianires
little ou big endian avec des types de tailles variables) ni pourquoi,
dans la solution actuelle je suis obligé d'utiliser une la variable
locale 'zero' égale à 0 car mon compilateur ne comprend pas la valeur
immédiate 0 de la même façon suivant les types (ou le mode
d'évalutation if ou while), sans signaler de warning, est-ce bien
normal ?

Carlos.

4 réponses

Avatar
Cyrille Karmann
(Carlos Bergadler) disait:
Salut,

j'aimerais trouver une méthode stable pour déterminer la valeur
maximale d'un type intégral signé ou non.


Il y a une raison quelconque de ne pas utiliser
std::numeric_limits<integer>::max() ?

ni pourquoi,
dans la solution actuelle je suis obligé d'utiliser une la variable
locale 'zero' égale à 0 car mon compilateur ne comprend pas la valeur
immédiate 0 de la même façon suivant les types (ou le mode
d'évalutation if ou while), sans signaler de warning, est-ce bien
normal ?


0 tout seul doit être considéré comme un int par le compilateur et
alors il couine à cause de la conversion... vous pouvez remplacer "zero"
par une conversion explicite "(integer) 0", je pense...

--
Cyrille

Avatar
Arnaud Meurgues
Carlos Bergadler wrote:

j'aimerais trouver une méthode stable pour déterminer la valeur
maximale d'un type intégral signé ou non.


Le plus simple et le plus portable est alors d'utilise numeric_limit :

signed char max = std::numeric_limits<char>::max();

typedef signed char integer; // ou autre...


C'est bizarre d'assimiler un integer à un signed char... À moins que
"integer" soit là pour signifier "type intégral quelconque".

mais j'espère qu'on peut faire mieux et je ne sais pas si c'est
"convenablement" protable


En matière de nombre, très peu de chose qu'on croit portable l'est. Il
existe des machines infernales où les représentations internes sont
absolument cauchemardesques.
En l'occurrence, cette méthode suppose que la représentation interne est
du complément à 2 pour les négatifs et que la représentation est binaire.
Elle ne devrait donc pas marcher dans le cas des EBCDIC (binaire codé
décimal) ni dans le cas des compléments à 1.
En règle générale, toute méthode numérique qui s'appuie sur la
représentation interne des nombre n'est pas portable.

Par ailleurs :

a*=2; // ou a+=a, on décale dans le "bon sens" jusqu'au


Si on veut faire un décalage, alors autant le dire explicitement :

a << 1;

je suis obligé d'utiliser une la variable
locale 'zero' égale à 0 car mon compilateur ne comprend pas la valeur
immédiate 0 de la même façon suivant les types (ou le mode
d'évalutation if ou while), sans signaler de warning, est-ce bien
normal ?


Par défaut, le compilateur suppose que 0 est un int. Donc, il fait
l'opération ~ sur un int avant de convertir le résultat en fonction du
type de l'opération qui suit. En mettant
max = ~(integer(0)) - max;
il ne devrait pas y avoir le même problème. Pour résumer, il faut
indiquer le type de 0.

--
Arnaud
(Supprimez les geneurs pour me répondre)

Avatar
cbergadler
Cyrille Karmann wrote in message news:<41055f2c$0$30101$...
Il y a une raison quelconque de ne pas utiliser
std::numeric_limits<integer>::max() ?


Je l'utilise mais j'ai besoin de résoudre certains cas ou
numeric_limits renvoie 0 (tandis que le chiffre est codé sur x octets
ordonnés sous forme binaire avec ou sans bit de signe). En fait il ne
semble y avoir que deux possibilités pour la position du signe (s'il y
en a un), donc je vais imbriquer deux test avec les décalages had-oc.

0 tout seul doit être considéré comme un int par le compilateur et
alors il couine à cause de la conversion... vous pouvez remplacer "zero"
par une conversion explicite "(integer) 0", je pense...


effectivement, je pensais que la conversion était implicite vers le
"bon" type.

Merci.

Avatar
drkm
(Carlos Bergadler) writes:

Cyrille Karmann wrote in message news:<41055f2c$0$30101$...

Il y a une raison quelconque de ne pas utiliser
std::numeric_limits<integer>::max() ?


Je l'utilise mais j'ai besoin de résoudre certains cas ou
numeric_limits renvoie 0


Tu veux dire que std::numeric_limits<integer>::max() retourne 0 pour
un type entier ?

--drkm, en recherche d'un stage : http://www.fgeorges.org/ipl/stage.html