web-dev-qa-db-fra.com

C division et plancher entier

En C, y a-t-il une différence entre la division entière a/b et le plancher (a/b) où a et b sont des entiers? Plus précisément, que se passe-t-il pendant les deux processus?

10
CodeKingPlusPlus

a/b fait la division entière. Si a ou b est négatif, le résultat dépend du compilateur (l'arrondi peut aller vers zéro ou vers l'infini négatif en pré-C99; en C99 +, l'arrondi va vers 0). Le résultat est de type int. floor(a/b) fait la même division, convertit le résultat en double, élimine la partie fractionnelle (inexistante) et renvoie le résultat sous forme de double.

10
Pete Becker

floor retourne une double tant que a / ba et b sont des nombres entiers donne une valeur entière.

Avec la distribution correcte, la valeur est la même.

Si l'opérateur typeof existait en C (ce n'est pas le cas), nous aurions:

(typeof (a /b)) floor(a / b) == a / b

EDIT: Maintenant, si la question est la suivante: existe-t-il une différence entre:

(double) (a / b)

et

floor(a / (double) b)

la réponse est oui. Les résultats diffèrent en ce qui concerne les valeurs négatives.

6
ouah

Il est possible de perdre des informations en convertissant un nombre entier en virgule flottante. Peu probable avec int et double, mais avec une légère altération:

#include <stdio.h>
#include <math.h>

int main(void)
{
    unsigned long long a = 9000000000000000003;
    unsigned long long b = 3;
    printf("a/b = %llu\n", a/b);
    printf("floor(a/b) = %f\n", floor(a/b));
    return 0;
}

Résultat:

a/b = 3000000000000000001
floor(a/b) = 3000000000000000000.000000
4
Alan Curry

En général, en supposant que les entiers soient représentables dans les types entier et virgule flottante, il n'y a pas de différence, mais la preuve n'est pas évidente. Le problème est qu’en virgule flottante, un arrondi se produit dans la division a/b, de sorte que la fonction de plancher ne s’applique pas à la valeur rationnelle exacte, mais à une valeur approximative. J'avais écrit un article sur le sujet: https://www.vinc17.net/research/publi.html#Lef2005b

En bref, le résultat que j’ai obtenu est que si a - b est exactement représentable dans le système à virgule flottante, alors floor (a/b), où a et b sont des nombres à virgule flottante (avec des valeurs entières), donne le Même résultat que la division entière a/b.

1
vinc17