Este sitio web usa cookies de terceros para analizar el tráfico y personalizar los anuncios. Si no está de acuerdo, abandone el sitio y no siga navegando por él. ×


3.2. Tipo de datos real

Cuando queremos almacenar datos con decimales, no nos sirve el tipo de datos "int". Necesitamos otro tipo de datos que sí esté preparado para guardar números "reales" (con decimales). Al igual que ocurría con los números enteros, tendremos más de un tipo de número real para elegir.

3.2.1. Coma fija y coma flotante

En el mundo de la informática hay dos formas de trabajar con números reales:

Casi cualquier lenguaje de programación actual va a emplear números de coma flotante. En C# corresponden al tipo de datos llamado "float".

// Ejemplo_03_02_01a.cs
// Números reales (1: float)
// Introducción a C#, por Nacho Cabanes

using System;

public class Ejemplo_03_02_01a
{
    public static void Main()
    {
        int i1 = 2, i2 = 3;
        float divisionI;

        Console.WriteLine("Vamos a dividir 2 entre 3 usando enteros");
        divisionI = i1/i2;
        Console.WriteLine("El resultado es {0}", divisionI);
        
        float f1 = 2, f2 = 3;
        float divisionF;

        Console.WriteLine("Vamos a dividir 2 entre 3 usando reales");
        divisionF = f1/f2;
        Console.WriteLine("El resultado es {0}", divisionF);
    }
}

Usando "float" sí hemos podido dividir con decimales. El resultado de este programa es:

Vamos a dividir 2 entre 3 usando enteros
El resultado es 0
Vamos a dividir 2 entre 3 usando reales
El resultado es 0,6666667

Ejercicios propuestos:

Ejercicio propuesto 3.2.1.1: Crea un programa que muestre el resultado de dividir 3 entre 4 usando números enteros y luego usando números de coma flotante.
Ejercicio propuesto 3.2.1.2: ¿Cuál sería el resultado de las siguientes operaciones, usando números reales? a=5; a/=2; a+=1; a*=3; --a;

3.2.2. Simple y doble precisión

En la mayoría de lenguajes de programación, contamos con dos tamaños de números reales para elegir, según si queremos guardar números con mayor cantidad de cifras o con menos. Para números con pocas cifras significativas (un máximo de 7, lo que se conoce como "un dato real de simple precisión") usaremos el tipo "float" y para números que necesiten más precisión (unas 15 cifras, "doble precisión") tenemos el tipo "double". En C# existe un tercer tipo de números reales, con mayor precisión todavía, el tipo "decimal", que se acerca a las 30 cifras significativas:

float double decimal
Tamaño en bits 32 64 128
Valor más pequeño -1,5 · 10-45 5,0 · 10-324 1,0 · 10-28
Valor más grande 3,4 · 1038 1,7 ·10308 7,9 · 1028
Cifras significativas715-1628-29

Así, podríamos plantear el ejemplo anterior con un "double" para obtener un resultado más preciso:

// Ejemplo_03_02_02a.cs
// Números reales (2: double)
// Introducción a C#, por Nacho Cabanes

using System;

public class Ejemplo_03_02_02a
{
    public static void Main()
    {
        double n1 = 2, n2 = 3;
        double division;

        Console.WriteLine("Vamos a dividir 2 entre 3");
        division = n1/n2;
        Console.WriteLine("El resultado es {0}", division);
    }
}

Ahora su resultado sería:

Vamos a dividir 2 entre 3
El resultado es 0,666666666666667

Si queremos dar un valor inicial a un dato "float", debemos llevar cuidado. Es válido darle un valor entero, como hemos hecho en el ejemplo anterior:Si queremos dar un valor inicial a un dato "float", debemos llevar cuidado. Es válido darle un valor entero, como hemos hecho en el ejemplo anterior:

float x = 2;

pero no podremos dar un valor que contenga cifras decimales, porque el compilador mostrará un mensaje de error diciendo que lo que aparece a la derecha es para él un dato "double" y el tipo de la variable es "float", así que se perderá precisión:

float pi = 3.14; // No válido

Hay un par de formas de solucionarlo. La más sencilla es añadir el sufijo "f" al número, para indicar al compilar que debe ser tratado como un "float":

float pi = 3.14f; // Dato correcto

Otra forma alternativa es forzar una "conversión de tipos", como veremos dentro de muy poco.

Así, podemos crear un programa que pida al usuario el radio de una circunferencia (que será un número entero) para mostrar la longitud de la circunferencia (cuyo valor será 2 * PI * radio) podría ser:

// Ejemplo_03_02_02a.cs
// Números reales (2: double)
// Introducción a C#, por Nacho Cabanes

using System;

public class Ejemplo_03_02_02a
{
    public static void Main()
    {
        double n1 = 2, n2 = 3;
        double division;

        Console.WriteLine("Vamos a dividir 2 entre 3");
        division = n1/n2;
        Console.WriteLine("El resultado es {0}", division);
    }
}

Ejercicios propuestos:

Ejercicio propuesto 3.2.2.1: Crea un programa que muestre el resultado de dividir 13 entre 6 usando números enteros, luego usando números de coma flotante de simple precisión y luego con números de doble precisión.
Ejercicio propuesto 3.2.2.2: Calcula el área de un círculo, dado su radio, que será un número entero (área = pi * radio al cuadrado)

3.2.3. Pedir números reales al usuario

Al igual que hacíamos con los enteros, podemos leer como cadena de texto, y convertir cuando vayamos a realizar operaciones aritméticas. Ahora usaremos Convert.ToDouble cuando se trate de un dato de doble precisión, Convert.ToSingle cuando sea un dato de simple precisión (float) y Convert.ToDecimal para un dato de precisión extra (decimal):

// Ejemplo_03_02_03a.cs
// Números reales: pedir al usuario
// Introducción a C#, por Nacho Cabanes

using System;

public class Ejemplo_03_02_03a
{
    public static void Main()
    {
        float primerNumero;
        float segundoNumero;
        float suma;

        Console.WriteLine("Introduce el primer número");
        primerNumero = Convert.ToSingle(Console.ReadLine());
        Console.WriteLine("Introduce el segundo número");
        segundoNumero = Convert.ToSingle(Console.ReadLine());
        suma = primerNumero + segundoNumero;

        Console.WriteLine("La suma de {0} y {1} es {2}", 
          primerNumero, segundoNumero, suma);
    }
}

Cuidado al probar este programa: aunque en el fuente debemos escribir los decimales usando un punto, como 123.456, al poner el ejecutable en marcha, cuando se pidan datos al usuario, parte del trabajo se le encarga al sistema operativo, de modo que si éste sabe que en nuestro país se usa la "coma" para separar los decimales, considerará que la coma es el separador correcto y no el punto, que será ignorado. Por ejemplo, ocurre si introducimos los datos 23,6 y 34.2 en la versión española de Windows 8 obtendremos como respuesta:

Introduce el primer número
23,6
Introduce el segundo número
34.2
La suma de 23,6 y 342 es 365,6

Ejercicios propuestos:

Ejercicio propuesto 3.2.3.1: Calcula el volumen de una esfera, dado su radio, que será un número de doble precisión (volumen = pi * radio al cubo * 4/3)
Ejercicio propuesto 3.2.3.2: Crea un programa que pida al usuario a una distancia (en metros) y el tiempo necesario para recorrerla (como tres números: horas, minutos, segundos), y muestre la velocidad, en metros por segundo, en kilómetros por hora y en millas por hora (pista: 1 milla = 1.609 metros).
Ejercicio propuesto 3.2.3.3: Halla las soluciones de una ecuación de segundo grado del tipo y = Ax2 + Bx + C. Pista: la raíz cuadrada de un número x se calcula con Math.Sqrt(x)
Ejercicio propuesto 3.2.3.4: Si se ingresan E euros en el banco a un cierto interés I durante N años, el dinero obtenido viene dado por la fórmula del interés compuesto: Resultado = e (1+ i)n Aplicarlo para calcular en cuanto se convierten 1.000 euros al cabo de 10 años al 3% de interés anual.
Ejercicio propuesto 3.2.3.5: Crea un programa que muestre los primeros 20 valores de la función y = x2 - 1
Ejercicio propuesto 3.2.3.6: Crea un programa que "dibuje" la gráfica de y = (x-5)2 para valores de x entre 1 y 10. Deberá hacerlo dibujando varios espacios en pantalla y luego un asterisco. La cantidad de espacios dependerá del valor obtenido para "y".
Ejercicio propuesto 3.2.3.7: Escribe un programa que calcule una aproximación de PI mediante la expresión: pi/4 = 1/1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 ... El usuario deberá indicar la cantidad de términos a utilizar, y el programa mostrará todos los resultados hasta esa cantidad de términos. Debes hacer todas las operacion con "double".

3.2.4. Conversión de tipos (typecast)

Cuando queremos convertir de un tipo de número a otro (por ejemplo, para quedarnos con la parte entera de un número real), tenemos dos alternativas:

Por ejemplo, podríamos retocar el programa que calculaba la longitud de la circunferencia, de modo que su resultado sea un "double", que luego convertiremos a "float" y a "int" forzando el nuevo tipo de datos:

// Ejemplo_03_02_04a.cs
// Números reales: typecast
// Introducción a C#, por Nacho Cabanes

using System;

public class Ejemplo_03_02_04a
{
    public static void Main()
    {
        double radio;
        float pi = (float) 3.141592654;
        double longitud;
        float longitudSimplePrec;
        int longitudEntera;

        Console.WriteLine("Introduce el radio");
        radio = Convert.ToDouble(Console.ReadLine());
        
        longitud = 2 * pi * radio;
        Console.WriteLine("La longitud de la circunferencia es");
        Console.WriteLine(longitud);
        
        longitudSimplePrec = (float) longitud;
        Console.WriteLine("Y con simple precisión");
        Console.WriteLine(longitudSimplePrec);
        
        longitudEntera = (int) longitud;
        Console.WriteLine("Y como número entero");
        Console.WriteLine(longitudEntera);
    }
}

Su resultado sería:

Introduce el radio
2,3456789
La longitud de la circunferencia es
14,7383356099727
Y con simple precisión
14,73834
Y como número entero
14

Ejercicio propuesto 3.2.4.1: Crea un programa que calcule la raíz cuadrada del número que introduzca el usuario. La raíz se deberá calcular como "double", pero el resultado se mostrará como "float"
Ejercicio propuesto 3.2.4.2: Crea una nueva versión del un programa que calcula una aproximación de PI mediante la expresión: pi/4 = 1/1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 (...) con tantos términos como indique el usuario. Debes hacer todas las operacion con "double", pero mostrar el resultado como "float".

3.2.5. Formatear números

En más de una ocasión nos interesará afinar la apariencia de los números en pantalla, para mostrar sólo una cierta cantidad de decimales: por ejemplo, nos puede interesar que una cifra que corresponde a dinero se muestre siempre con dos cifras decimales, o que una nota se muestre redondeada, sin decimales, o con sólo un decimal.

Una forma de conseguirlo es crear una cadena de texto a partir del número, usando "ToString". A esta orden se le puede indicar un dato adicional, que es el formato numérico que queremos usar, por ejemplo: suma.ToString("0.00")

Algunos de los códigos de formato que se pueden usar son:

Vamos a probarlos en un ejemplo:

// Ejemplo_03_02_05a.cs
// Formato de números reales
// Introducción a C#, por Nacho Cabanes

using System;

public class Ejemplo_03_02_05a
{
    public static void Main()
    {
        double numero = 12.34;
        
        Console.WriteLine( numero.ToString("N1") );
        Console.WriteLine( numero.ToString("N3") );
        Console.WriteLine( numero.ToString("0.0") );
        Console.WriteLine( numero.ToString("0.000") );
        Console.WriteLine( numero.ToString("#.#") );
        Console.WriteLine( numero.ToString("#.###") );
    }
}

El resultado de este ejemplo sería:

12,3
12,340
12,3
12,340
12,3
12,34

Ejercicio propuesto 3.2.5.1: El usuario de nuestro programa podrá teclear dos números de hasta 12 cifras significativas. El programa deberá mostrar el resultado de dividir el primer número entre el segundo, utilizando tres cifras decimales.
Ejercicio propuesto 3.2.5.2: Crea un programa que use tres variables x,y,z. Las tres serán números reales, y nos bastará con dos cifras decimales. Se deberá pedir al usuario los valores para las tres variables y mostrar en pantalla el valor de x2 + y - z (con exactamente dos cifras decimales).
Ejercicio propuesto 3.2.5.3: Calcula el perímetro, área y diagonal de un rectángulo, a partir de su ancho y alto (perímetro = suma de los cuatro lados; área = base x altura; diagonal, usando el teorema de Pitágoras). Muestra todos ellos con una cifra decimal.
Ejercicio propuesto 3.2.5.4: Calcula la superficie y el volumen de una esfera, a partir de su radio (superficie = 4 * pi * radio al cuadrado; volumen = 4/3 * pi * radio al cubo). Usa datos "doble" y muestra los resultados con 5 cifras decimales.

3.2.6. Cambios de base

Un uso alternativo de ToString es el de cambiar un número de base. Por ejemplo, habitual¬mente trabajamos con números decimales (en base 10), pero en informática son también muy frecuentes la base 2 (el sistema binario) y la base 16 (el sistema hexadecimal). Podemos convertir un número a binario o hexadecimal (o a base octal, menos frecuente) usando Convert.ToString e indicando la base, como en este ejemplo:

// Ejemplo_03_02_06a.cs
// De decimal a hexadecimal y binario
// Introducción a C#, por Nacho Cabanes

using System;

public class Ejemplo_03_02_06a
{
    public static void Main()
    {
        int numero = 247;
        
        Console.WriteLine( Convert.ToString(numero, 16) );
        Console.WriteLine( Convert.ToString(numero, 2) );
    }
}

Su resultado sería:

f7
11110111

(Si quieres saber más sobre el sistema hexadecimal, mira los apéndices al final de este texto)

Ejercicios propuestos:

Ejercicio propuesto 3.2.6.1: Crea un programa que pida números (en base 10) al usuario y muestre su equivalente en sistema binario y en hexadecimal. Debe repetirse hasta que el usuario introduzca el número 0.
Ejercicio propuesto 3.2.6.2: Crea un programa que pida al usuario la cantidad de rojo (por ejemplo, 255), verde (por ejemplo, 160) y azul (por ejemplo, 0) que tiene un color, y que muestre ese color RGB en notación hexadecimal (por ejemplo, FFA000).
Ejercicio propuesto 3.2.6.3: Crea un programa para mostrar los números del 0 a 255 en hexadecimal, en 16 filas de 16 columnas cada una (la primera fila contendrá los números del 0 al 15 –decimal-, la segunda del 16 al 31 –decimal- y así sucesivamente).

Para convertir en sentido contrario, de hexadecimal o binario a decimal, podemos usar Convert.ToInt32, como se ve en el siguiente ejemplo. Es importante destacar que una constante hexadecimal se puede expresar precedida por "0x", como en "int n1 = 0x13;" (donde n1 tendría el valor 16+3=19, expresado en base 10). En los lenguajes C y C++, un valor precedido por "0" se considera octal, de modo que para "int n2 = 013;" el valor decimal de n2 sería 8+3=11, pero en C# no es así: un número que empiece por 0 (no por 0x) se considera que está escrito en base 10, como se ve en este ejemplo:

// Ejemplo_03_02_06b.cs
// De hexadecimal y binario a decimal
// Introducción a C#, por Nacho Cabanes

using System;

public class Ejemplo_03_02_06b
{
    public static void Main()
    {
        int n1 = 0x13;
        int n2 = Convert.ToInt32("1a", 16);
        
        int n3 = 013; // No es octal, al contrario que en C y C++
        int n4 = Convert.ToInt32("14", 8);
        
        int n5 = Convert.ToInt32("11001001", 2);
        
        Console.WriteLine( "{0} {1} {2} {3} {4}", 
            n1, n2, n3, n4, n5);
    }
}

Que mostraría:

19 26 13 12 201

Ejercicios propuestos:

Ejercicio propuesto 3.2.6.4: Crea un programa que pida números binarios al usuario y muestre su equivalente en sistema hexadecimal y en decimal. Debe repetirse hasta que el usuario introduzca la palabra "fin".