División en C++

Adnan Ashraf 12 octubre 2023
  1. Reglas de precedencia y asociatividad en C++
  2. Peculiaridad de la división de enteros en C++
  3. Encasillar y resolver la peculiaridad de la división de enteros en C++
División en C++

Este artículo trata sobre las reglas de división en C++.

Primero, veremos las reglas de precedencia y encasillamiento para la división. Más adelante, discutiremos una peculiaridad común de la división de enteros conocida como el reparto de corte.

Reglas de precedencia y asociatividad en C++

El término precedencia especifica el orden de evaluación de los operadores en una expresión. Por ejemplo, algunas de las reglas de precedencia para los operadores de C++ desde el nivel más alto hasta el nivel más bajo son las siguientes:

  1. Las expresiones escritas entre paréntesis se evalúan primero.
  2. Los operadores * y \ tienen el mismo nivel de precedencia.
  3. Del mismo modo, los operadores + y - tienen el mismo nivel de precedencia.
  4. Si dos operadores con el mismo nivel de precedencia ocurren en una expresión, entonces los operadores se evalúan de izquierda a derecha (excepto el operador de asignación (=). También se conoce como asociatividad de operadores.

Por ejemplo, considere la siguiente expresión mixta:

(1*2)+3/3*2-1

La expresión anterior se evalúa de la siguiente manera:

  1. En el primer paso, el operador * se evalúa primero porque está entre paréntesis con el nivel de precedencia más alto. Después del primer pase, la expresión queda así 2+3/3*2-1.

  2. El operador / se evalúa primero en el segundo paso. Aunque los operadores * y / tienen el mismo nivel de precedencia, los operadores con los mismos niveles de precedencia se evalúan de izquierda a derecha.

    Después del segundo pase, la expresión parece 2+1*2-1.

  3. En el tercer paso, se evalúa el operador de multiplicación ya que tiene la precedencia más alta entre los otros operadores en la expresión. Tras el tercer pase, la expresión se reduciría a 2+2-1.

  4. El operador + se evalúa primero en el cuarto paso. Aunque los operadores + y - tienen el mismo nivel de precedencia, los operadores con igual nivel de precedencia se evalúan de izquierda a derecha.

    Tras el cuarto pase, la expresión se convierte en 4-1.

  5. Finalmente, se evalúa el operador - y obtenemos la expresión reducida a un único valor de 3.

Ahora, tenemos suficientes antecedentes sobre precedencia de operadores y asociatividad. Veamos algunas de las peculiaridades del operador / en C++.

Peculiaridad de la división de enteros en C++

Cuando dividimos dos números enteros en C++, el operador de división devuelve solo la parte entera de la respuesta. La parte fraccionaria de la respuesta es cortada.

La razón principal es el encasillamiento implícito por parte del compilador. Antes de saltar al encasillamiento, veamos un ejemplo de división de enteros.

#include <iostream>
using namespace std;

int main() {
  int m = 10;
  int n = 7;
  float a = m / n;
  cout << "The answer after division is:" << a << endl;
}

Producción :

The answer after division is:1

El resultado confirma que el compilador de C++ omite la parte fraccionaria de la respuesta. Primero comprendamos el encasillamiento para comprender la causa raíz de esta peculiaridad y las posibles soluciones.

Encasillar y resolver la peculiaridad de la división de enteros en C++

Typecasting significa cambiar el tipo de una variable. El encasillamiento puede ser implícito o explícito.

Encasillamiento explícito

Esto lo realizan los programadores de forma explícita. La palabra clave static_cast se utiliza para el encasillamiento explícito.

Este tipo de conversión se realiza en tiempo de compilación.

El siguiente código resuelve el problema de la división de enteros mediante el uso de encasillamiento explícito. La línea 6 del siguiente código convierte estáticamente los valores de m y n en valores de coma flotante; por lo tanto, el resultado de la división también será un número flotante.

#include <iostream>
using namespace std;

int main() {
  int m = 10;
  int n = 7;
  float a =
      static_cast<float>(m) / static_cast<float>(n);  // static explicit casting
  cout << "The answer after explicit typecasting is: " << a << endl;
}

Producción :

The answer after explicit typecasting is: 1.42857

Encasillamiento implícito

El compilador realiza automáticamente el encasillamiento implícito. El compilador evalúa la expresión según los tipos de datos utilizados en una expresión.

El compilador siempre evalúa los resultados en un tipo de datos superior entre todos los tipos de datos utilizados en la expresión dada.

La conversión implícita es la causa raíz de la peculiaridad de la división de enteros. Cuando se utilizan dos operandos enteros con la división aritmética, la evaluación se convierte implícitamente al tipo de datos int, lo que hace que se recorte la parte decimal del resultado.

Podemos resolver el problema de la división de enteros cambiando el tipo de un operando de división con algún tipo de coma flotante, como se demuestra en el siguiente código:

#include <iostream>
using namespace std;

int main() {
  float a = 10.0 / 7;
  cout << "The answer after implicit typecasting is: " << a << endl;
}

Producción :

The answer after implicit typecasting is: 1.42857

En el ejemplo anterior, el numerador 10.0 es el valor flotante y el denominador es un valor entero. Como el tipo de datos flotante es mayor que el tipo de datos entero, el compilador convierte implícitamente el valor resultante en el tipo de datos flotante.

Hay algunas otras peculiaridades asociadas con el operador de división en C++, como División por error cero y División de punteros que los geeks pueden explorar más a fondo.

Artículo relacionado - C++ Math