Pourquoi la division entière en C # renvoie-t-elle un entier et non un float?

Est-ce que quelqu'un sait pourquoi la division entière en C# renvoie un entier et non un flottant? Quelle est l'idée derrière tout cela? (Est-ce seulement un héritage de C / C++?)

En C#:

float x = 13 / 4;   
//imagine I used have an overridden == operator here to use epsilon compare
if (x == 3.0)
   print 'Hello world';

Le résultat de ce code serait:

'Hello world'

Strictement parlant, il n'y a pas de division entière (la division par définition est une opération qui produit un nombre rationnel, les entiers sont un très petit sous-ensemble.)

100
demandé sur Boann 2012-06-01 17:32:44

7 réponses

Bien qu'il soit courant pour les nouveaux programmeurs de faire cette erreur d'effectuer une division entière alors qu'ils voulaient réellement utiliser une division à virgule flottante, dans la pratique, la division entière est une opération très courante. Si vous supposez que les gens l'utilisent rarement, et que chaque fois que vous faites la division, vous devrez toujours vous rappeler de lancer à des points flottants, vous vous trompez.

Tout d'Abord, la division entière est un peu plus rapide, donc si vous avez seulement besoin d'un nombre entier, donc, on voudrait pour utiliser l'algorithme plus efficace.

Deuxièmement, il existe un certain nombre d'algorithmes qui utilisent la division entière, et si le résultat de la division était toujours un nombre à virgule flottante, vous seriez obligé d'arrondir le résultat à chaque fois. Un exemple du haut de ma tête est de changer la base d'un nombre. Le calcul de chaque chiffre implique la division entière d'un nombre avec le reste, plutôt que la division en virgule flottante du nombre.

À cause de ceux-ci (et d'autres raisons connexes), la division entière entraîne un entier. Si vous voulez obtenir la division en virgule flottante de deux entiers vous aurez juste besoin de se rappeler de lancer un à un double/float/decimal.

61
répondu Servy 2012-06-01 13:42:56

Voir c # Spécification . Il existe trois types d'opérateurs de division

  • division entière
  • division à virgule flottante
  • division décimale

Dans votre cas, nous avons une division entière, avec les règles suivantes appliquées:

La division arrondit le résultat vers zéro, et la valeur absolue de le résultat est le plus grand entier qui est moins que le valeur absolue du quotient des deux opérandes. Le résultat est zéro ou positif lorsque les deux opérandes ont le même signe et zéro ou négatif lorsque les deux opérandes ont des signes opposés.

Je pense que la raison pour laquelle C# utilise ce type de division pour les entiers (certaines langues renvoient un résultat flottant) est le matériel - la division des entiers est plus rapide et plus simple.

67
répondu Sergey Berezovskiy 2012-06-01 13:57:32

Chaque type de données est capable de surcharger chaque opérateur. Si le numérateur et le dénominateur sont des entiers, le type entier effectuera l'opération de division et retournera un type entier. Si vous voulez une division à virgule flottante, vous devez convertir un ou plusieurs des nombres en types à virgule flottante avant de les diviser. Par exemple:

int x = 13;
int y = 4;
float x = (float)y / (float)z;

Ou, si vous utilisez des littéraux:

float x = 13f / 4f;

Gardez à l'esprit que les points flottants ne sont pas précis. Si vous vous souciez de la précision, utilisez quelque chose comme le type décimal, à la place.

28
répondu Steven Doggart 2012-06-01 13:42:40

Puisque vous n'utilisez aucun suffixe, les littéraux 13 et 4 sont interprétés comme entiers:

Manuel de:

Si le littéral n'a pas de suffixe, il a la première de ces types dans lequel sa valeur peut être représentée: int, uint, long, ulong.

Ainsi, puisque vous déclarez 13 comme entier, la division entière sera effectuée:

Manuel de:

Pour une opération de la forme x / y, opérateur binaire la résolution de surcharge est appliquée pour sélectionner une implémentation d'opérateur spécifique. Les opérandes sont convertis en types de paramètre de l'opérateur et le type du résultat est le type de retour de l'opérateur.

Les opérateurs de division prédéfinis sont listés ci-dessous. Les opérateurs calculent tous le quotient de x et Y.

Division entière:

int operator /(int x, int y);
uint operator /(uint x, uint y);
long operator /(long x, long y);
ulong operator /(ulong x, ulong y);

Et donc l'arrondi vers le bas se produit:

La division arrondit le résultat vers zéro, et la valeur absolue du résultat est le plus grand entier qui est inférieur à la valeur absolue du quotient des deux opérandes. Le résultat est zéro ou positif lorsque les deux opérandes ont le même signe et zéro ou négatif lorsque les deux opérandes ont des signes opposés.

Si vous faites ce qui suit:

int x = 13f / 4f;

Vous recevrez une erreur du compilateur, car une division à virgule flottante (l'opérateur / de 13f) entraîne un flottant, qui ne peut pas être converti en int implicitement.

Si vous voulez que la division soit une division à virgule flottante, vous devrez faire du résultat un float:

float x = 13 / 4;

Notez que vous diviserez toujours des entiers, qui seront implicitement convertis en float: le résultat sera 3.0. Pour déclarer explicitement les opérandes comme float, en utilisant le suffixe f (13f, 4f).

10
répondu CodeCaster 2012-06-01 13:51:00

C'est juste une opération de base .

Rappelez-vous quand vous avez appris à diviser. Au début, nous avons résolu 9/6 = 1 with remainder 3.

9 / 6 == 1  //true
9 % 6 == 3 // true

L' /-opérateur en combinaison avec l' %-opérateur sont utilisés pour récupérer ces valeurs.

6
répondu L. Monty 2014-12-18 01:40:39

Pourrait être utile:

double a = 5.0/2.0;   
Console.WriteLine (a);      // 2.5

double b = 5/2;   
Console.WriteLine (b);      // 2

int c = 5/2;   
Console.WriteLine (c);      // 2

double d = 5f/2f;   
Console.WriteLine (d);      // 2.5
3
répondu primalshade 2016-12-09 11:24:40

Le résultat sera toujours du type qui a la plus grande plage du numérateur et du dénominateur. Les exceptions sont byte et short, qui produisent int (Int32).

var a = (byte)5 / (byte)2;  // 2 (Int32)
var b = (short)5 / (byte)2; // 2 (Int32)
var c = 5 / 2;              // 2 (Int32)
var d = 5 / 2U;             // 2 (UInt32)
var e = 5L / 2U;            // 2 (Int64)
var f = 5L / 2UL;           // 2 (UInt64)
var g = 5F / 2UL;           // 2.5 (Single/float)
var h = 5F / 2D;            // 2.5 (Double)
var i = 5.0 / 2F;           // 2.5 (Double)
var j = 5M / 2;             // 2.5 (Decimal)
var k = 5M / 2F;            // Not allowed

Il n'y a pas de conversion implicite entre les types à virgule flottante et le type décimal, donc la division entre eux n'est pas autorisée. Vous devez explicitement lancer et décider lequel vous voulez (Decimal a plus de précision et une plage plus petite par rapport aux types à virgule flottante).

1
répondu z m 2017-05-01 19:16:03