¿Por qué la división de enteros en C# devuelve un entero y no un flotador?


¿Alguien sabe por qué la división de enteros en C# devuelve un entero y no un flotador? ¿Cuál es la idea detrás de esto? (¿ Es solo un legado 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';

El Resultado de este código sería:

'Hello world'

Estrictamente hablando, no hay tal cosa como la división entera (división por definición es una operación que produce un número racional, los enteros son un subconjunto muy pequeño de los cuales.)

 100
Author: Boann, 2012-06-01

7 answers

Mientras que es común para los nuevos programadores cometer este error de realizar la división entera cuando realmente querían usar la división en coma flotante, en la práctica real la división entera es una operación muy común. Si estás asumiendo que la gente rara vez lo usa, y que cada vez que hagas división siempre necesitarás recordar lanzar a puntos flotantes, estás equivocado.

En primer lugar, la división entera es bastante más rápida, por lo que si solo necesita un resultado de número entero, uno querría para utilizar el algoritmo más eficiente.

En segundo lugar, hay una serie de algoritmos que usan la división entera, y si el resultado de la división siempre fuera un número de coma flotante, se vería obligado a redondear el resultado cada vez. Un ejemplo de la parte superior de mi cabeza es cambiar la base de un número. El cálculo de cada dígito implica la división entera de un número junto con el resto, en lugar de la división en coma flotante del número.

Debido a estos (y otros razones relacionadas), la división de enteros resulta en un entero. Si desea obtener la división en coma flotante de dos enteros, solo tendrá que recordar lanzar uno a una double/float/decimal.

 61
Author: Servy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-01 13:42:56

Véase la especificación de C# . Hay tres tipos de operadores de división

  • División entera
  • División en coma flotante
  • División decimal

En su caso tenemos división entera, con las siguientes reglas aplicadas:

La división redondea el resultado hacia cero, y el valor absoluto de el resultado es el mayor entero que es menor que el valor absoluto del cociente de los dos operandos. El resultado es cero o positivo cuando los dos operandos tienen el mismo signo, y cero o negativo cuando los dos operandos tienen signos opuestos.

Creo que la razón por la que C# usa este tipo de división para enteros (algunos lenguajes devuelven resultados flotantes) es que la división de enteros por hardware es más rápida y simple.

 67
Author: Sergey Berezovskiy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-01 13:57:32

Cada tipo de datos es capaz de sobrecargar a cada operador. Si tanto el numerador como el denominador son enteros, el tipo entero realizará la operación de división y devolverá un tipo entero. Si desea división en coma flotante, debe convertir uno o más de los números a tipos de coma flotante antes de dividirlos. Por ejemplo:

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

O, si está utilizando literales:

float x = 13f / 4f;

Tenga en cuenta que los puntos flotantes no son precisos. Si te importa la precisión, usa algo así como el tipo decimal, en su lugar.

 28
Author: Steven Doggart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-01 13:42:40

Dado que no se usa ningún sufijo, los literales 13 y 4 se interpretan como enteros:

Manual:

Si el literal no tiene sufijo, tiene el primero de estos tipos en el que se puede representar su valor: int, uint, long, ulong.

Por lo tanto, ya que se declara 13 como entero, se realizará la división de enteros:

Manual:

Para una operación de la forma x / y, operador binario la resolución de sobrecarga se aplica para seleccionar una implementación de operador específica. Los operandos se convierten a los tipos de parámetros del operador seleccionado, y el tipo del resultado es el tipo de retorno del operador.

Los operadores de división predefinidos se enumeran a continuación. Todos los operadores calculan el cociente de x e y.

División entera:

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

Y así se redondea hacia abajo:

La división redondea el resultado hacia cero, y el valor absoluto del resultado es el entero más grande posible que es menor que el valor absoluto del cociente de los dos operandos. El resultado es cero o positivo, cuando los dos operandos tienen el mismo signo, y cero o negativo cuando los dos operandos tienen signos opuestos.

Si haces lo siguiente:

int x = 13f / 4f;

Recibirá un error del compilador, ya que una división en coma flotante (el operador / de 13f) resulta en un flotador, que no se puede convertir a int implícitamente.

Si desea que la división sea una división en coma flotante, tendrá que hacer que el resultado sea flotante:

float x = 13 / 4;

Observe que todavía dividirá enteros, que implícitamente se lanzarán a flotar: el resultado será 3.0. Para declarar explícitamente los operandos como flotadores, usando el sufijo f (13f, 4f).

 10
Author: CodeCaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-01 13:51:00

Es solo una operación básica.

Recuerda cuando aprendiste a dividir. Al principio resolvimos 9/6 = 1 with remainder 3.

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

El operador /-en combinación con el operador %se utilizan para recuperar esos valores.

 6
Author: L. Monty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-18 01:40:39

Podría ser útil:

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
Author: primalshade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-09 11:24:40

El resultado siempre será del tipo que tiene el mayor rango del numerador y el denominador. Las excepciones son byte y short, que producen 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

No hay conversión implícita entre los tipos de coma flotante y el tipo decimal, por lo que no se permite la división entre ellos. Tienes que emitir explícitamente y decidir cuál quieres (el decimal tiene más precisión y un rango más pequeño en comparación con los tipos de punto flotante).

 1
Author: z m,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-01 19:16:03