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 bc - 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)(bc) - 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 = bc
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:)
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
Ç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).
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
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
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.