Por que a divisão de números inteiros em C # retorna um inteiro e não um float?

Alguém sabe porque divisão inteira em c # retorna um inteiro e não um float? Qual é a ideia por trás disso? (É apenas um legado de C / C ++?)

Em c #:

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

O resultado deste código seria:

 'Hello world' 

Estritamente falando, não existe a divisão por inteiro (a divisão por definição é uma operação que produz um número racional, os inteiros são um subconjunto muito pequeno dos quais).

Embora seja comum para o novo programador cometer esse erro de realizar a divisão de números inteiros quando eles realmente pretendiam usar a divisão de ponto flutuante, na prática real a divisão de números inteiros é uma operação muito comum. Se você está assumindo que as pessoas raramente o usam, e que toda vez que você fizer uma divisão você sempre precisará se lembrar de lançar pontos flutuantes, está enganado.

Em primeiro lugar, a divisão de números inteiros é um pouco mais rápida, portanto, se você precisar apenas de um resultado com um número inteiro, seria necessário usar o algoritmo mais eficiente.

Em segundo lugar, há vários algoritmos que usam divisão inteira e, se o resultado da divisão fosse sempre um número de ponto flutuante, você seria forçado a arredondar o resultado todas as vezes. Um exemplo do topo da minha cabeça é mudar a base de um número. Calcular cada dígito envolve a divisão inteira de um número junto com o restante, em vez da divisão do ponto flutuante do número.

Devido a essas razões (e outras relacionadas), a divisão inteira resulta em um inteiro. Se você deseja obter a divisão de ponto flutuante de dois inteiros, você só precisa lembrar de converter um para um double / float / decimal .

Veja a especificação do C #. Existem três tipos de operadores de divisão

  • Divisão Inteira
  • Divisão de ponto flutuante
  • Divisão decimal

No seu caso, temos Integer division, com as seguintes regras aplicadas:

A divisão arredonda o resultado para zero, e o valor absoluto do resultado é o maior inteiro possível que é menor que o valor absoluto do quociente dos dois operandos. O resultado é zero ou positivo quando os dois operandos possuem o mesmo sinal e zero ou negativo quando os dois operandos possuem sinais opostos.

Eu acho que o motivo pelo qual o C # usa esse tipo de divisão para inteiros (algumas linguagens retornam resultados flutuantes) é a divisão de inteiros de hardware é mais rápida e simples.

Cada tipo de dados é capaz de sobrecarregar cada operador. Se tanto o numerador quanto o denominador forem inteiros, o tipo inteiro executará a operação de divisão e retornará um tipo inteiro. Se você quiser divisão de ponto flutuante, você deve converter um ou mais dos números em tipos de ponto flutuante antes de dividi-los. Por exemplo:

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

ou, se você estiver usando literais:

 float x = 13f / 4f; 

Tenha em mente que os pontos flutuantes não são precisos. Se você se preocupa com a precisão, use algo como o tipo decimal.

Como você não usa nenhum sufixo, os literais 13 e 4 são interpretados como inteiros:

Manual :

Se o literal não tiver sufixo, ele terá o primeiro desses tipos em que seu valor pode ser representado: int , uint , long , ulong .

Assim, desde que você declare 13 como inteiro, a divisão inteira será executada:

Manual :

Para uma operação do formato x / y, a resolução de sobrecarga do operador binário é aplicada para selecionar uma implementação de operador específica. Os operandos são convertidos nos tipos de parâmetros do operador selecionado e o tipo do resultado é o tipo de retorno do operador.

Os operadores de divisão predefinidos estão listados abaixo. Todos os operadores calculam o quociente de x e y.

Divisão Inteira:

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

E assim, o arredondamento ocorre:

A divisão arredonda o resultado para zero, e o valor absoluto do resultado é o maior inteiro possível que é menor que o valor absoluto do quociente dos dois operandos. O resultado é zero ou positivo quando os dois operandos possuem o mesmo sinal e zero ou negativo quando os dois operandos possuem sinais opostos.

Se você fizer o seguinte:

 int x = 13f / 4f; 

Você receberá um erro do compilador, uma vez que uma divisão de ponto flutuante (o / operador de 13f ) resulta em um ponto flutuante, que não pode ser convertido int intencionalmente.

Se você quer que a divisão seja uma divisão de ponto flutuante, você terá que fazer o resultado flutuar:

 float x = 13 / 4; 

Observe que você ainda dividirá inteiros, que serão implicitamente convertidos em float: o resultado será 3.0 . Declarar explicitamente os operandos como float, usando o sufixo f ( 13f , 4f ).

É apenas uma operação básica .

Lembre-se quando você aprendeu a dividir. No começo, resolvemos 9/6 = 1 with remainder 3 .

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

O / -operador em combinação com o% -operador é usado para recuperar esses valores.

Pode 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 

O resultado será sempre do tipo que tem o maior alcance do numerador e do denominador. As exceções são byte e short, que produzem 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 

Não há conversão implícita entre os tipos de ponto flutuante e o tipo decimal, portanto, a divisão entre eles não é permitida. Você tem que explicitamente converter e decidir qual deles você deseja (Decimal tem mais precisão e um menor intervalo comparado aos tipos de ponto flutuante).