Saltar al contenido
Topos Uranos

Resumen

Una expresión aritmética no se calcula de izquierda a derecha como se lee, sino según una estructura oculta, su árbol, que fijan la precedencia de los operadores, su asociatividad y los paréntesis; y en cada nodo de ese árbol el tipo de los operandos decide qué operación se hace, de modo que 7 / 2 vale 3 y 7 / 2.0 vale 3.5. Esta clase estudia los cinco operadores aritméticos de C++ con enteros y con reales; la división entera y el resto, que desde C++11 truncan hacia cero, de donde se sigue que el resto toma el signo del dividendo y difiere del resto de la división euclídea cuando el dividendo es negativo; la manera de obtener el resto euclídeo; el árbol de una expresión; el tipo del resultado cuando los operandos son de tipos distintos, y las dos maneras en que una expresión aritmética entera pierde su significado: dividir por cero y desbordar en un cálculo intermedio.

Objetivos de aprendizaje

  1. Calcular el cociente y el resto de la división entera en C++, también con operandos negativos, y relacionarlos con el cociente y el resto de la división euclídea.
  2. Dibujar el árbol de una expresión aritmética según la precedencia y la asociatividad, y calcular su valor.
  3. Predecir el tipo del resultado de una operación entre operandos de tipos distintos.
  4. Usar la división entera y el resto para descomponer cantidades: las cifras de un número, una duración en horas y minutos, un día de la semana.

Los operadores aritméticos

C++ tiene cinco operadores aritméticos binarios: la suma +, la resta -, el producto *, la división / y el resto %; tiene además el menos unario, que cambia el signo de su único operando, como en -x. Los cuatro primeros se aplican a enteros y a reales; el resto, solo a enteros. Ahora bien, la misma escritura no designa la misma operación en todos los casos: si los dos operandos de / son enteros, la división es entera y su resultado es un entero, el cociente sin la parte fraccionaria; si alguno es real, la división es real. La clase Caracteres, booleanos, conversiones y constantes mostró la consecuencia más visible de esta regla, que double r{7 / 2}; guarda 3: la división se hizo entre enteros antes de que el resultado se convirtiera en real.

EjemploLos cinco operadores con dos enteros

El programa aplica los cinco operadores a 17 y 5, y repite la división con un dividendo real.

Programa en C++
#include <print>​int main(){    const int a{17};    const int b{5};    std::println("{} + {} = {}", a, b, a + b);    std::println("{} - {} = {}", a, b, a - b);    std::println("{} * {} = {}", a, b, a * b);    std::println("{} / {} = {}", a, b, a / b);    std::println("{} % {} = {}", a, b, a % b);    const double x{17.0};    std::println("{} / {} = {}", x, b, x / b);}
Salida
17 + 5 = 2217 - 5 = 1217 * 5 = 8517 / 5 = 317 % 5 = 217 / 5 = 3.4

17 entre 5 da 3 y sobran 2: son el cociente y el resto de repartir 17 objetos en grupos de 5. La última línea divide un real entre un entero y obtiene 3.4. Hay que advertir que std::println escribe el real 17.0 como «17»: el marcador vacío escribe la representación más corta del valor, de modo que lo escrito no revela el tipo; para verlo, se piden decimales con {:.1f}.

El operador % no admite reales. Escribir 7.5 % 2 no es un error de lógica que el programa descubra al ejecutarse, sino un error de compilación: el compilador dice que los operandos de tipos double e int no son válidos para el operador.

Programa en C++
#include <print>​int main(){    std::println("{}", 7.5 % 2);}
Mensajes de error del compilador
main.cpp: In function ‘int main()’:main.cpp:5:28: error: invalid operands of types ‘double’ and ‘int’ to binary ‘operator%’    5 |     std::println("{}", 7.5 % 2);      |                        ~~~ ^ ~

El resto de una división real existe, y lo calcula la función std::fmod de la cabecera <cmath>, que se estudiará en la clase Bits y biblioteca matemática, junto con la potencia: C++ no tiene operador de potencia, y 2 ^ 3 no vale 8, sino otra cosa que se explicará allí.