C : capacité de variables

Bonjour,

J’aimerai avoir des précisions sur la capacité des varibles en C :

int a, b, c, d;
a = bc - d;
Si on est sur que b
c - b sera < à INT_MAX est ce que le calcul sera juste si bc dépasse INT_MAX ?
Si non, on peut ecrire ca ? : a = (float)(b
c) - d

Est ce qu’on peut faire en sorte que si un calcul est superieur à INT_MAX on prenne INT_MAX comme résultat?
Comme ca peut etre?
if (bc > INT_MAX)
a = INT_MAX
else
a = b
c

De manière logique si bc > INT_MAX ssi b >= INT_MAX (ou c) et c > 1. Sauf que tu es en informatique, où les entiers sont bornés, bc sous ces mêmes conditions peut très bien être inférieur à b*c (sans bornes).

Essaye plutôt: a = ((float)b)*((float)c)-d. Sinon, tu fais une multiplication sur le domaine entier puis tu passes en flottant.

Pour ta seconde question: oui. Si tu vérifies les valeurs de b & c (selon les critères que je te fournis plus haut). De toute façon, c’est simple : si tu fais b*c, avec b et c deux nombres positifs, et que tu as un nombre négatif, c’est que tu as un problème:)

heu je comprends pas bien là.
Exemple bete :
INT_MAX = 4
b = c = 3;

b * c > INT_MAX et pourtant b et c sont < INT_MAX
Edité le 14/01/2008 à 15:18

Voir même, passe en flottant tout court, sauf si tu es sûr de pouvoir assurer le non dépassement.

je veux pouvoir assurer le non dépassement et rester en entier tant que possible pour des problèmes de performances.
Mais peux tu m’expliquer pourquoi tu as écrit : b*c > INT_MAX ssi b >= INT_MAX (ou c) et c > 1 ?
Edité le 14/01/2008 à 15:37

Ben :

b*c > INT_MAX

Ça implique que b > INT_MAX et c > 1, ou que b > 1 et c > INT_MAX.

Pour le non dépassement, je sais pas si honnêtement cela vaut le coup de vérifier tous les paramètres et se priver des flottants (mieux taillé pour, même si bornés eux aussi).

Tu veux faire quoi exactement?

INT_MAX = 4
b = c = 3;
donc b < INT_MAX et c < INT_MAX mais b * c > INT_MAX
Je rate un truc?

Du traitement d’image, donc manipulation de gros tableaux, plus rapide en entier.
Edité le 14/01/2008 à 17:04

non j’ai oublié des cas, dsl (j’étais au boulot, … ça va comme excuse bidon?) :slight_smile:

b*c > INT_MAX => b > INT_MAX/c

En fait, je pense que le mieux c’est de faire l’opération et de vérifier que le résultat est cohérent : ça ne sera pas cohérent si :

  • si tu multiplies par un nombre négatif, le résultat est forcément négatif, d’où débordement si positif
  • si tu multiplies deux nombres positif, le résultat n’est pas cohérent s’il est négatif (INT_MAX*INT_MAX = débordement)

Mais est ce que le résultat peut etre cohérent mais qu’il y ai quand meme un débordement?

J’en doute. Sauf éventuellement à utiliser un type plus grand, pour faire le calcul (par exemple long, sur archi. 64bit uniquement), et forcer la limite à INT_MAX.

Le résultat n’est pas cohérent dès qu’un élément de l’opération dépasse INT_MAX. La soustraction que tu effecturas après la multiplication utilisera l’overflow de l’opération précédente à savoir dans ce cas :
-INT_MAX + (b * c - INT_MAX).
Edité le 15/01/2008 à 17:48

Comme je disais, la seule façon, ça serait ça:

int r = b*c;
if (b > 0) {
if (c > 0 && r < 0) {débordement} // b, c > 0 => r > 0
else if (c < 0 && r > 0) {débordement} // b > 0, c < 0 => r < 0
} else if (b < 0) {
if (c > 0 && r > 0) {débordement} // b < 0, c > 0 => r < 0
else if (c < 0 && r < 0) {débordement} // b, c => r > 0
}

Sachant qu’il faut recommencer pour l’addition avec d’autres règles :slight_smile:

Tu as plus vite fait de faire des recherches sur l’assembleur, me semble que le processeur met un flag “overflow”, et donc inutile de faire ça si le proco le fait.

    unsigned int a;
    unsigned int b;
    unsigned int c;
    unsigned int d;
    
    printf( "Entier a :\n");
    scanf( "%u", &a);
    printf( "Entier b : ( Max %u )\n", UINT_MAX / a);
    scanf( "%u", &b);
    printf( "Entier c : \n");
    scanf( "%u", &c);
    
    if (((float)UINT_MAX / (float)b)< (float)a) {
        d = UINT_MAX;
    } else {
        if( ( a*b ) < c ) {
            d = 0;
        } else {
            d = ( a*b ) - c;
        }
    }
    
    printf( "Resultat : %u", d );

Edité le 16/01/2008 à 00:48

ok, je vous remercie