Tipos de Datos
Daniel Herrera P.
danherrera@udec.cl
Tipos de datos en C
•
Representación de datos en C está relacionada con la arquitectura del computador
)Memoria se direcciona por bytes
)Procesadores tienen registros de 1 2 4 8 bytes )Procesadores tienen registros de 1, 2, 4, 8 bytes
•
Un dato cualquiera tiene
)Un tipo (caracter, entero, punto flotante) )Un valor (que puede ser indeterminado)
)Una posición de memoria donde está almacenado
2
Tipo de dato char
•
Al menos 8 bits
)Debe poder almacenar un caracter ASCII
•
Rangos mínimos
i d h 128 127
)signed char: -128 a 127 )unsigned char: 0 a 255
•
Rango de char depende del compilador
)Por omisión, char puede ser signed o unsigned3
Tipo de dato short int
•
Al menos 16 bits
•
Puede abreviarse a short
•
Rangos mínimos
)short: -32768 (-215) a 32767 (215– 1) )unsigned short: 0 a 65535 (216 - 1)
4
Tipo de dato int
•
Al menos 16 bits
•
Rangos mínimos
)int: -32768 (-215) a 32767 (215– 1) i d i t 0 65535 (216 1) )unsigned int: 0 a 65535 (216 - 1)
•
16 bits, 32 bits o 64 bits?
)A elección de la implementación
)Generalmente tamaño de registros de CPU
5
Tipo de dato long int
•
Al menos 32 bits
•
Puede abreviarse como long
•
Rangos mínimos
)long: -2147483648 (-231) a 2147483647 (231– 1) )unsigned long: 0 a 4294967295 (232– 1)
6
Tipo de dato long long int
•
Al menos 64 bits
•
Puede abreviarse como long long
•
Introducido en estándar ISO C99
•
Rangos mínimos
)long long: -263a 263– 1 )unsigned long long: 0 a 264– 1
7
Archivo<limits.h>
•
Archivo que define los límites usados por el compilador
)Residente en \Dev-Cpp\include
Define rangos de los tipos de datos
•
Define rangos de los tipos de datos
)CHAR_BIT: número de bits por byte`8 bits
)CHAR_MIN: valor mínimo para char )CHAR_MAX: valor máximo para char
8
Constantes en <limits.h>
Tipo Min.
signed
Max.
signed
Max.
unsigned
char SCHAR_MI
N
SCHAR_MA X
UCHAR_MAX
short SHRT_MIN SHRT_MAX USHRT_MAX
int INT_MIN INT_MAX UINT_MAX
long LONG_MIN LONG_MAX ULONG_MAX
9
Operador sizeof()
•
Operador retorna el tamaño de un tipo de datos en bytes
)sizeof(long)≥ sizeof(int) ≥ sizeof(short) )sizeof(char)= 1
)sizeof(short)= 2 )sizeof(long)= 4 )sizeof(int)= 2, 4 o 8 )sizeof(long long)= 8
10
Constantes char
•
Letras, números y símbolos ASCII son constantes de tipo char
)‘A’= ASCII 65 )‘F’= ASCII 70 )F = ASCII 70 )‘A’ + ‘F’= 135 )‘\t’: tab (ASCII 9)
)‘\n’: avance de línea (ASCII 13)
)‘\0’: ASCII 0 (no confundir con ‘0’: ASCII 48)
Constantes enteras
•
Números tienen tipo int por omisión
)Números long int se especifican con L ó l )234: tipo int)234U: tipo unsigned int )234L: tipo long int
•
Números hexadecimales precedidos de 0x
)0x234= 23416= 56410•
Números octales precedidos de 0
)0234= 2348 = 15610Porqué usar constantes?
•
Conveniencia y claridad en el código
numero = numero – 48;numero = numero – 060;
numero = numero ‘0’;
numero = numero – 0 ;
•
Todos hacen lo mismo
)Todos corresponden a la misma secuencia de bits: 001110002
13
Promoción de enteros
•
Código puede mezclar tipos
•
El tipo más corto es promovido al tipo mayor antes de la operación
ó f ó
•
Promoción no pierde información
•
‘B’ + 5 ⇒ char + int
)Resultado es de tipo int14
Rebalse de enteros
int k;
(k * 1024);
•
Qué pasa si int es de 16 bits?
)Si k es menor de 32 resultado cabe en 16 bits )Si k es menor de 32, resultado cabe en 16 bits )Si k es mayor de 32, rebalse!
)Este es un error de tiempo de ejecución
•
Solución: usar constante long y promoción
k * 1024L;15
Curiosidades del C
•
0 igual a 0U: Verdadero
•
-1 < 0: Verdadero
•
-1 < 0U: Falso
)Operación se realiza en aritmética sin signo )Operación se realiza en aritmética sin signo
•
2147483647 > -2147483647 - 1: V
•
2147483647U > -2147483647 - 1: F
)Operación se realiza en aritmética sin signo•
2147483647 > (int) 2147483648U: V
)Cast convierte número sin signo a con signo16
Rebalse en sumas en C
•
Rebalse (Overflow) se produce si resultado de suma excede capacidad de representación del tipo de datos
)Operación se transforma en aritmética modular )Operación se transforma en aritmética modular
•
Aritmética entera con signo
)Puede ocurrir rebalse positivo•
Aritmética con signo (complemento a 2)
)Pueden ocurrir rebalses positivos y negativos17
Enumeraciones
•
Permite definir secuencias de enteros
•
Usa constantes simbólicas
)enum dias {LUNES, MARTES, MIERCOLES, JUEVES VIERNES SABADO DOMINGO};
JUEVES, VIERNES, SABADO, DOMINGO};
)Una vez definidas, no se deben redefinir!
•
Equivalente a
)int LUNES = 0, MARTES = 1, MIERCOLES = 2, JUEVES = 3, VIERNES = 4, SABADO = 5, DOMINGO = 6;
18
Enumeraciones
•
Enumeración siempre comienza en 0
)Pueden darse valores explícitamente)Puede usar números enteros positivos y negativos )Constantes no especificadas toman valor de )Constantes no especificadas toman valor de
constante anterior + 1
)enum numeros {UNO = 1,DOS, CUATRO = 4, CINCO, OCHO = 8};
)X = CINCO + OCHO; /* X vale 13 */
19
Punto flotante
•
Números decimales representados en codificación llamada “punto flotante”
)float: precisión simple
`Tamaño típico: 32 bits
`Tamaño típico: 32 bits )double: precisión doble
`Tamaño típico: 64 bits
)long double: precisión extendida
`Tamaño típico: 80 bits
20
Archivo <float.h>
Tipo Mínimo Máximo
float FLT MIN_ FLT MAX_
double DBL_MIN DBL_MAX
Long double LDBL_MIN LDBL_MAX
21
Rangos de tipos (aproximados)
•
float
)10-38≤ float ≤ 1038 )-1038≤ float ≤ -10-38
•
double double
)10-308≤ double ≤ 10308 )-10308≤ double ≤ -10-308
•
long double
)10-4932≤ long double ≤ 104932 )-104932≤ long double ≤ -10-4932
22
Constantes de punto flotante
•
Números con punto decimal tienen tipo double por omisión
)2.3421: tipo double
Números float se especifican con F ó f
•
Números float se especifican con F ó f
)2.3421f: tipo float•
Números long double se especifican con L ó l
)2.3421L: tipo long doubleConstantes de punto flotante
•
Pueden especificarse también en notación científica
)2.34e21equivalente a 2.34x1021 )6 02e 23equivalente a 6 02x10-23 )6.02e-23equivalente a 6.02x1023
•
Constantes también pueden ser números hexadecimales
)0x14p10equivalente a 20x210 = 2048010
`P indica exponente binario
Aritmética de punto flotante
•
Actualmente, en forma generalizada, se usa formato IEEE-754
•
Codifica números de la forma (-1)
s·0.m·2
e d l i)scorresponde al signo )mcorresponde a la mantisa )ecorresponde al exponente
•
En computación, siempre se usa base 2
•
Exponente e puede ser positivo o negativo
25
Números de precisión simple
•
Precisión simple (float) utiliza 32 bits
)1 bit de signo s, 23 de mantisa my 8 deexponente e
•
Exponente
eva entre 126 y +127
•
Exponente e va entre -126 y +127
)Codificado como e+127•
Mantisa m toma valores 0 ≤ m < 1
)Parte fraccionaria fes 1+ m(“1 implícito”)•
Estos son los valores normalizados
)No representan el 0!26
Números de precisión doble
•
Precisión simple (double) utiliza 64 bits
)1 bit de signo s, 52 de mantisa my 11 deexponente e
•
Exponente
eva entre 1022 y +1023
•
Exponente e va entre -1022 y +1023
)Codificado como e+1023•
Mantisa m toma valores 0 ≤ m < 1
)Parte fraccionaria fes 1+ m(“1 implícito”)27
Valores denormalizados
•
Bits del exponente e toman valor 0
)Precisión simple: exponente es -127 )Precisión doble: exponente es -1023V l f i i
fl d l ti
•
Valor fraccionario f es valor de la mantisa m
)Sin el 1 implícito•
Permiten representar números cercanos al 0
28
Valores especiales
•
Representación del 0
)Bit de signo ses 0, bits del exponente eson 0s y mantisa mes 0
)-0 0: Bit de signoses 1 bits del exponenteeson )0.0: Bit de signo ses 1, bits del exponente eson
0s y mantisa mes 0
•
Bits del exponente e son sólo 1s
)Si mantisa mes 0, número es +∞ ó -∞)Si mantisa mes diferente de 0, número es NaN (Not a Number)
`Ejemplo: Raíz de -1
29
Ejemplo de conversión a punto flotante
•
Convertir entero 12345 a precisión simple
)1234510es 110000001110012)Forma normalizada: 1.10000001110012x213 )Eliminando el 1 y completando a 23 bits, se tiene
m= 10000001110010000000000 )El exponente es e= 127 + 13 = 14010=
100011002
)El signo ses 0 (número positivo) )El resultado completo es 0x4640E400, o 0 10001100 100000011100100000000002
30
Ejemplo de conversión
•
Convertir 0x40490FDB a su equivalente decimal en punto flotante
)010000000100100100001111110010112 )Signo 0 implica número positivo
)Exponente 128 implicaExponente 128 implica eees 1es 1
)Mantisa 100100100001111110010112 implica número con el 1 implícito es
1.100100100001111110010112, que es 1.570710
)Número es entonces1.5707x21=3.1414
31
Ejemplos precisión simple
Descripción Exponente Fracción Valor Valor decimal
Cero 00…00 0….00 0 0.0
Denorm.
mínimo 00…00 0….01 2-23x2-126 1.4x10-45 Denorm. 00…00 1….11 (1-2-23) x2-126 1.2x10-38 Denorm.
máximo 00…00 1….11 (1 2 ) x2 1.2x10
Normal
mínimo 00…01 0….00 1x2-126 1.2x10-38
Uno 01…11 0….00 1x20 1.0
Normal
máximo 11…10 1….11 (2-2-23)x2126 3.4x1038
32
Ejemplos precisión doble
Descripción Exponente Fracción Valor Valor decimal
Cero 00…00 0….00 0 0.0
Denorm.
mínimo
00…00 0….01 2-52x2-1022 4.9x10-324 Denorm. 00…00 1….11 (1-2-52) x2-1022 2.2x10-308
máximo ( )
Normal
mínimo 00…01 0….00 1x2-1022 2.2x10-308
Uno 01…11 0….00 1x20 1.0
Normal
máximo 11…10 1….11 (2-2-52)x2126 1.8x10308
33
Punto flotante en Intel x86
•
Procesadores Intel x86 tiene registros especiales de 80 bits para punto flotante
)Formato tiene 1 bit de signo, 63 de mantisa y 15 de exponente
`Incluye además 1 bit para el 1 implícito
)Todas las operaciones de punto flotante entre registros se realizan usando números de 80 bits
`Resultados luego se truncan y/o redondean a 64 o 32 bits
)Estándar C tiene tipo de dato long double para forzar este comportamiento
34
Conversión de tipos
•
Conversión entre enteros y punto flotante se hace mediante un cast
)Se fuerza la conversión a otro tipo indicando el tipo nuevo entre paréntesis
tipo nuevo entre paréntesis int a = (int) 4.566; /* a vale 4 */
float b = (float) 2; /* b vale 2.0 */
double c = (double) ‘A’; /* c vale 65.0 */
Conversión de tipos
•
Ojo con los paréntesis!
)Importante al usar división entera float a = 5/2; /* a vale 2.0 */
float b = 5 0/2; /* b vale 2 5 */
float b = 5.0/2; / b vale 2.5 / float c = (float) 5/2; /* c vale 2.5 */
float d = (float) (5/2); /* d vale 2.0 */
float e = ((float) 5)/2; /* e vale 2.5 */
Ejercicios de punto flotante
•Indique si estas aseveraciones son V ó F
)Suponga
1. x == (int) (float) x;
2. x == (int) (double) x;
3. f == (float) (double) f;
4. d == (float) d;
5. f == -(-f);
int x;
float f;
double d;
( );
6. 2/3 == 2/3.0;
7. d < 0.0 implica (d*2) < 0.0 8. d > f implica –f > -d 9. d*d >= 0.0 10.(d + f) – d == f
37
Conversión de tipos
•
Es posible usar un cast para convertir de un número entero a otro de menor tamaño
)Compilador se va a quejar, pero es posible!
)Resultado es indefinido )Resultado es indefinido char a = 424343242;
•
También puede hacerse con números de punto flotante
float b = 4.5342e45;
38
Declaraciones
Daniel Herrera P.
danherrera@udec.cl
Formato
•
Declaración básica
tipo lista_de_nombres;)Declaración reserva espacio en memoria para la variable
•
Ejemplos Ejemplos
int I;char letra1, letra2, letra3;
unsigned short direccion;
•
Declaraciones terminan con ;
)El ; es el terminadoren C40
Nombres
•
Pueden incluir mayúsculas, minúsculas, números, _
)No pueden comenzar con un dígito
C disting e entre ma úsc las minúsc las
•
C distingue entre mayúsculas y minúsculas
)Abc≠ abc ≠ ABC•
Longitud ilimitada
)Estándar permite ignorar caracteres > 31
41
Inicialización de variables
•
Asignación de valor inicial
int I = 15;char letra1 = ‘A’, letra2, letra3;
unsigned short direccion = 0x3F65;
unsigned short direccion = 0x3F65;
unsigned numero = 034;
•
No es necesario inicializar variables
)Queda a criterio del programador42
Variables en memoria
)I: entero (4 bytes)
`Valor inicial: 00000015 )letra1: caracter (1 byte)
`Valor inicial: ‘A’
)letra2 letra3: caracter
0000 0015
??A I letra1
Un byte
letra2
)letra2, letra3: caracter
`Valor inicial indeterminado )direccion: short (2 bytes)
`Valor inicial: 0x3F65 )numero: entero (4 bytes)
`Valor inicial: 034
??3F 6500 0000 Memoria letra3 direccion
034 numero
43
Declaración de Vectores
•Vectores unidimensionales char vector[10];
)10 elementos, vector[0] a vector[9]
`Numeración de vectores siempre comienza en 0
)Acceso directo a elementos
vector[0]
vector[5]
Acceso directo a elementos
`vector[5] = 10;
)Compilador no verifica límites
`Qué pasa si se accesa vector[10] ?
`Acceso a datos fuera del vector
Memoria vector[10]
44
typedef
•
Mecanismo que permite definir nuevos nombres para tipos de datos
typedef ushort unsigned short;
ushort corto mascorto;
ushort corto, mascorto;
•
Simplifica el código
)Facilita los cambios de tipo de dato
45
Alcance de una variable
•
Sección de código donde una variable dada es válida
)Alcance de nivel de bloque )Alcance de nivel de archivo )Alcance de nivel de archivo
)Nombres de variables en un alcance deben ser únicos
)Es posible que variables de un mismo nombre existan en alcances diferentes
46
Alcances en el código
int a;
{ int f;
{
int f g i;
•Colores indican alcances de las variables
)atiene alcance de archivo int f, g, i;
} {
int i;
} }
)f, g, itienen alcance al bloque verde
)itiene alcance al bloque rojo
)ftiene alcance al bloque azul
Alcance de bloque
•
Bloque: secuencia de código delimitada por llaves { y }
)Variable definida al comienzo de un bloque esVariable definida al comienzo de un bloque es visible en todo el bloque
)Bloques pueden ser anidados
)Variable declarada en bloque interno domina sobre variable del mismo nombre en bloque externo
Alcance de archivo
•
Identificadores declarados fuera de todo bloque son visibles en todo el archivo
)“Variables globales”
)Las dos primeras líneas del ejemplo )Las dos primeras líneas del ejemplo
•
Todos los nombres de funciones tienen alcance de archivo
49
Variables externas
•En proyectos grandes, es posible que el código fuente esté dividido en varios archivos
• externdeclara una variable global como definida en otro archivo
•Es costumbre definir todas las variables globales en archivos separados
)Archivos de encabezado (“header files”)
`Extensión .h
50
Variables externas
int a;
int b;
float c;
#include “codigo.h”
extern int a;
codigo1.c codigo.h
#include “codigo.h”
extern int b;
extern float c;
codigo2.c
51
Ejemplo de declaraciones
#include <stdio.h>
int main(void) { int entero = 100;
float flotante = 331.79;
double doble = 8.44e+11;
h t ‘W’
char caracter = ‘W’;
_Bool verdad = 0;
printf(“entero = %d\nflotante = %f\ndoble = %lf\ncaracter =
%c\nverdad = %i\n”, entero, flotante, doble, caracter, verdad);
}
52
printf()
•
Función estándar de impresión en consola
•
Usa formatos de control para imprimir sus argumentos
%d t i
)%d: enteros con signo )%u: enteros sin signo )%c: caracteres
)%f: punto flotante de precisión simple )%lf: punto flotante de precisión doble
53
Resultado de la ejecución
entero = 100 flotante = 331.790009 doble = 844000000000.000000 caracter = W
verdad = 0 verdad = 0
)Nótese que los números de punto flotante se imprimen con 6 decimales
)Error en flotante?
`Representación interna genera un error de precisión
54
Operadores
Daniel Herrera P.
danherrera@udec.cl
Operadores en C
•
Aritméticos
•
Incremento/Decremento
•
De Relación
•
Lógicos
•
Manejo de Bits
•
Asignación
•
Condicional
56
Operadores aritméticos
•
Operaciones estándar
)+, -, *, /, %•
%: Operador módulo (aplicable a enteros)
R l d l di i ió
)Retorna el resto de la división entera 35%4 = 3
9%12 = 9
)No aplicable a datos float o double
`Números negativos? Depende del compilador
57
Ejemplo de %
•
Año bisiesto: divisible por 4 pero no por 100, excepto si es divisible por 400
if ((bis%4 == 0 && bis%100 != 0) || bis%400 == 0) if ((bis%4 0 && bis%100 ! 0) || bis%400 0)
printf(“%d es bisiesto\n”, bis);
else
printf(“%d no es bisiesto\n”, bis);
58
División de números enteros
•
La división de dos números enteros entrega un entero
)Dividir 5/2 da como resultado 2 (entero) )Resultado será punto flotante si uno de los
operadores es punto flotante float f = 5/2; /* f vale 2.0 */
float f = 5/2.0; /* f vale 2.5 */
float f = (float) 5/2; /* f vale 2.5 */
)Conversión de tipos se aplica al dato siguiente al cast
Incremento/Decremento
•
++ aumenta en 1
•
- - decrementa en 1
)Postincremento y preincremento
`A B++C i l l d B A l i t B
`A = B++;Copia el valor de B en A y luego incrementa B
`A = ++B; Incrementa B y luego copia el valor de B en A )Postdecremento y predecremento
`A = B--;Copia el valor de B en A y decrementa B
`A = --B; decrementa B y copia el valor de B en A
De Relación
•
Operadores de desigualdad
)>, >=, <, <=•
Operadores de igualdad
! )==, !=
•
El lenguaje C utiliza el operador = para la asignación y == para la comparación
61
Lógicos
•
Operadores lógicos
)&& (AND) y || (OR)•
Se evalúan de izquierda a derecha
E l ió d i l i l d V ó
)Evaluación se detiene ante el primer resultado V ó F (Cortocircuito)
if ((c > = 0) || (j++ < n))
)Si la primera condición se cumple, la segunda nunca se evalúa y j no se incrementa
62
Cortocircuito OR
•Cond1OR Cond2
•Evalúa de izquierda a derecha
•Si Cond1es Verdadero, no es necesario evaluar Cond1 Cond2 OR
F F F no es necesario evaluar
Cond2: OR será Verdadero
•Si Cond1es Falso, es necesario evaluar Cond2 para definir valor de OR
F F F
F V V
V F V
V V V
63
Cortocircuito AND
•Cond1AND Cond2
•Evalúa de izquierda a derecha
•Si Cond1es Falso, no es necesario evaluar Cond : Cond1 Cond2 AND
F F F necesario evaluar Cond2: AND será Falso
•Si Cond1es Verdadero, es necesario evaluar Cond2para definir valor de AND
F F F
F V F
V F F
V V V
64
Manejo de Bits
•
&: AND de bits
•
|: OR de bits
•
^: XOR de bits
•
<<: Desplazamiento a la izquierda
•
>>: Desplazamiento a la derecha
•
~: Complemento a 1 (negación)
65
&& vs. &
•&&: AND lógico int a = 5, b = 13;
c = a && b;
•Equivale a AND entre
i bl d d
•&: AND de bits int a = 5, b = 13;
c = a & b;
•Equivale a AND entre
l l bi i
variables verdaderas )a y b son != 0 )Valor final de c:
Verdadero (1)
los valores binarios )a = 01012
)b = 11012
)a AND b = 01012
)Valor final de c es 5
66
AND y OR de bits
•
AND: Enmascarar un conjunto de bits
n = n & 0177;)Hace 0 todos los bits menos los 7 inferiores
•
OR: Activar un conjunto de bits
n = n | 0xaaaaaaaa;)Hace 1 todos los bits impares del entero
•
XOR: Invertir un conjunto de bits
n = n ^ 0x55555555;)Invierte todos los bits pares del entero
67
Desplazamiento de bits
•
x<<n: corre los bits de x n posiciones a la izquierda (multiplicar x por 2
n)
•
x>>n: corre los bits de x n posiciones a la derecha (dividir x por 2
n)
derecha (dividir x por 2
n)
)Si x = 0x00AF (17510)x>>3 = 0x15 (2110) x<<3 = 0x0578 (140010)
`Qué pasa con un corrimiento a la derecha de un número negativo?
68
Extensión de signo
•
Desplazamiento a la derecha de un entero con signo extiende el signo
)Ejemplo: sea
unsigned char a = 0xFC;
unsigned char a = 0xFC;
signed char b = 0xFC;
)(a >> 2)es 0x3F )(b >> 2)es 0xFF
)El signo de b se replica 2 veces a la izquierda
69
Asignaciones
•
Formato: Direccion = Expresion
)La expresión del lado derecho del signo se evalúa y su resultado se almacena en la dirección del lado izquierdoq
)Ejemplo: A = A + B
`Evaluar A + B y almacenar el resultado en la dirección de memoria especificada por A
)Ejemplo: Z = Y = X = 4
`Asigna el valor 4 a las variables Z, Y y X
70
Operadores de asignación
•
j = j + 2 puede escribirse como j += 2
•
Operadores de asignación:
)+=, -=, *=, /=, %=, <<=, >>=, &=, ^=, |=
•
expr1 op= expr2 p p p equivale a expr1 = (expr1) q p ( p ) op (expr2)
)x *= y + 1 equivale a x = x*(y + 1)
Precedencia y Asociatividad
•
Indica qué operadores se evalúan primero y en qué orden
)Usar paréntesis para modificar precedencia
•
C no especifica orden de evaluación de los operadores
operadores
)Qué valor imprime esta línea?
printf(“%d %d\n”, n++, n/=2);
`Depende de que operando se procesa primero )En qué elemento de a[] se almacena i?
a[i] = i++;
Precedencia de operadores (1)
() [] -> . Izquierda a derecha
! ~ ++ -- + -(unarios) *& (cast) sizeof() Derecha a izquierda
* / % Izquierda a derecha
+ - Izquierda a derecha
<< >> Izquierda a derecha
< <= > >= Izquierda a derecha
== != Izquierda a derecha
& Izquierda a derecha
73
Precedencia de operadores (2)
^ Izquierda a derecha
| Izquierda a derecha
&& Izquierda a derecha
|| Izquierda a derecha
?: Derecha a izquierda
= += -= *= /= %= &= ^=^|= <<= >>= Derecha a izquierda
, Izquierda a derecha
zOperadores en misma línea tienen misma precedencia
74
Ejemplos de precedencia
•
Caso básico: multiplicar antes que sumar
2 + 4*5 = 22•
División, multiplicación y módulo se asocian de i q ierda a derecha
de izquierda a derecha
5*3/5 = 33/5*5 = 0 3/5%5 = 0
75