Buscar

06. Tipos de Dados Ponto-Flutuante

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 47 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 47 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 47 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Ju
d
so
n
 S
an
to
s 
S
an
ti
ag
o
TIPO PONTO-FLUTUANTE
Tipos Básicos de Dados
Introdução
 O segundo maior grupo de tipos básicos de 
dados são os tipos ponto-flutuante
 Números em ponto-flutuante são números 
com uma parte fracionária (números reais)
 Ex.: 2.5, 3.14159, 122442.32
 Tipos ponto-flutuante fornecem uma faixa de 
valores maior que os tipos inteiros
 Se um número é muito grande para o tipo long
long, pode-se utilizar um ponto flutuante
Introdução
 O computador armazena um número real em 
duas partes: um valor (mantissa) e um fator 
de escala (expoente)
 Os números 34.1245 e 34124.5 são idênticos a 
não ser pela posição da sua vírgula
0.341245 100
0.341245 100000
Ponto-Flutuante
Valor Escala
34.1245
34124.5
=
=
Introdução
 Na memória, o fator de escala não é 
armazenado como um multiplicador, 
mas sim como um expoente
 0.341245 * 102 = 34.1245
 0.341245 * 105 = 34124.5
0.341245 2
0.341245 5
Ponto-Flutuante
Mantissa Expoente
34.1245
34124.5
=
=
Tipos Ponto-Flutuante
 A linguagem C++ tem três tipos ponto 
flutuante:
 float 
 double
 long double
 A principal diferença entre os tipos está:
 Número de dígitos significativos para a mantissa
 Valor máximo para o expoente
Tipos Ponto-Flutuante
 O que são os dígitos significativos ?
 143.06 tem 5 dígitos significativos
 4.50 tem 2 dígitos significativos
0.14306 3
0.45 1
143.06
4.5
=
=
Mantissa Expoente
Tipos Ponto-Flutuante
 Quanto maior a largura de bits usada para:
 Mantissa: maior a precisão do número
 Expoente: maior a magnitude do número
0.31415 1 3.1415=
Mantissa Expoente
Largura de bits = 16 bits
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Tipos Ponto-Flutuante
 Os tipos ponto-flutuante têm as seguintes 
larguras de bits na linguagem C++:
 float tem pelo menos 32 bits
 double tem pelo menos 48 bits 
(e é pelo menos tão grande quanto float)
 long double tem pelo menos o mesmo número de 
bits que double
Mantissa Expoente
Largura de bits
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Tipos Ponto-Flutuante
 Na prática, normalmente os valores são:
 float tem 32bits
 double tem 64 bits
 long double tem 64, 80, 96 ou 128 bits
 Os valores específicos para uma plataforma 
podem ser encontrados no arquivo de 
cabeçalho cfloat
#include <cfloat>
Tipos Ponto-Flutuante
#include <iostream>
#include <cfloat>
using namespace std;
int main()
{
cout << "Numero de Dígitos Significativos" << endl;
cout << "float: " << FLT_DIG << endl;
cout << "double: " << DBL_DIG << endl;
cout << "long double: " << LDBL_DIG << endl;
cout << "Valores Máximos do Expoente" << endl;
cout << "float: " << FLT_MAX_10_EXP << endl;
cout << "double: " << DBL_MAX_10_EXP << endl;
cout << "long double: " << LDBL_MAX_10_EXP << endl;
cout << "Numero de Bits na Mantissa" << endl;
cout << "float: " << FLT_MANT_DIG << endl;
cout << "double: " << DBL_MANT_DIG << endl;
cout << "long double: " << LDBL_MANT_DIG << endl;
system("pause");
return 0;
}
Tipos Ponto-Flutuante
 A saída do programa (Linux/g++):
Número de Dígitos Significativos
float : 6
double : 15
long double: 18
Valores Máximos do Expoente
float : 38
double : 308
long double: 4932
Número de Bits na Mantissa
float : 24
double : 53
long double: 64
Tipos Ponto-Flutuante
 A saída do programa (Windows8/VC++2012):
Número de Dígitos Significativos
float : 6
double : 15
long double: 15
Valores Máximos do Expoente
float : 38
double : 308
long double: 308
Número de Bits na Mantissa
float : 24
double : 53
long double: 53
Tipos Ponto-Flutuante
 Os tipos int e float ambos têm 32 bits, mas o 
computador representa-os de forma 
completamente diferente na memória
0
8 bits
(expoente)
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 1 1 1 1 1 0 0
23 bits
(mantissa)
0 0 1 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
float (32 bits) = 0.15625
int (32 bits) = 1042284544
1 bit
(sinal)
Constantes Ponto-Flutuante
 Uma constante ponto-flutuante pode ser 
representada de duas formas:
 Usando a notação decimal padrão
 Usando a notação exponencial
12.34 // ponto-flutuante
939001.32 // ponto-flutuante
0.00023 // ponto-flutuante
8.0 // também ponto-flutuante
2.52e+8 // pode usar e ou E, + é opcional
8.33E-4 // expoente pode ser negativo
7E5 // o mesmo que 7.0E+05
-18.32e13 // pode ter + ou – na frente
Constantes Ponto-Flutuante
 A notação E:
 A forma mE+n significa mova o ponto decimal n 
casas para a direita, e mE-n significa mova o 
ponto decimal n casas para a esquerda
+5.37E+16
Sinal - ou + (opcional)
Pode usar E (maiúsculo) ou e (minúsculo)
Sinal pode ser +/ - ou omitido
Sem espaços
Ponto decimal não é 
necessário se for 
seguido por zeros 
Constantes Ponto-Flutuante
 A notação E garante que um número será 
representado como ponto-flutuante
 O sinal da frente se aplica a mantissa, o sinal 
no expoente se aplica ao fator de escala
70.0 // valor ponto-flutuante
70 // valor inteiro
70E // ponto-flutuante igual a 70.0
-8.33E4 // é igual a -83300
8.33E-4 // é igual a 0.000833
-8.33E-4 // é igual a -0.000833
Precisão do Ponto-Flutuante
#include <iostream>
using namespace std;
int main()
{
// imprime números sempre com 6 casas decimais
cout.setf(ios_base::fixed, ios_base::floatfield);
float fltvar = 10.0 / 3.0; // bom para até 6 dígitos
double dblvar = 10.0 / 3.0; // bom para até 15 dígitos
float milhao = 1.0e6;
cout << "float var = " << fltvar;
cout << ", vezes um milhao = " << milhao * fltvar << endl;
cout << "double var = " << dblvar;
cout << ", vezes um milhao = " << milhao * dblvar << endl;
system("pause");
return 0;
}
Precisão do Ponto-Flutuante
 A saída do programa:
 A função setf() fixa o número de casas 
decimais mostradas após a vírgula
 A variável tipo float garante a precisão para 6
dígitos, a variável double garante a precisão 
para 15 dígitos
float var = 3.333333, vezes um milhao = 3333333.250000
double var = 3.333333, vezes um milhao = 3333333.333333
Precisão do Ponto-Flutuante
#include <iostream>
using namespace std;
int main()
{
float a = 2.34E+8;
float b = a + 1.0f;
cout << "a = " << a << endl;
cout << "b - a = " << b - a << endl;
system("pause");
return 0;
}
Saída do Programa:
a = 2.34e+8
b – a = 0
Ponto-Flutuante
 Vantagens:
 Eles podem representar valores entre dois 
números inteiros
 Devido ao fator de escala, podem representar 
uma faixa de valores maior que os tipos inteiros
 Desvantagens:
 Operações com pontos-flutuantes são mais lentas 
que operações com inteiros*
 Pontos-flutuantes perdem precisão
Operadores Aritméticos
 C++ fornece operadores para cinco cálculos 
aritméticos básicos:
 Soma (+)
 Subtração (-)
 Multiplicação (*)
 Divisão (/)
 Módulo (%)
(Resto da Divisão)
int rodas = 4 + 2;
Expressão
Operador
Operando Operando
Operadores Aritméticos
#include <iostream>
using namespace std;
int main()
{
float num1, num2;
cout << "Entre com um número: ";
cin >> num1;
cout << "Entre com outro número: ";
cin >> num2;
cout << "num1 = " << num1 << "; num2 = " << num2 << endl;
cout << "num1 + num2 = " << num1 + num2 << endl;
cout << "num1 - num2 = " << num1 - num2 << endl;
cout << "num1 * num2 = " << num1 * num2 << endl;
cout << "num1 / num2 = " << num1 / num2 << endl; 
system("pause");
return 0;
}
Operadores Aritméticos
 A saída do programa:
 cout mostrao resultado com até 6 dígitos, 
arredondando o valor se ele tiver mais que 6 
dígitos significativos
Entre com um número: 50.25
Entre com outro número: 11.17
num1 = 50.25; num2 = 11.17
num1 + num2 = 61.42 
num1 - num2 = 39.08
num1 * num2 = 561.292 // 561.2925
num1 / num2 = 4.49866 // 4.498657117278424
Precedência de Operadores
 Qual o resultado da expressão abaixo?
 Quando mais de um operador pode ser 
aplicado ao mesmo operando, C++ usa 
regras de precedência para decidir qual 
operador aplicar primeiro:
 Multiplicação/Divisão/Módulo
 Soma/Subtração
int total = 3 + 4 * 5; // 35 ou 23
int total = 3 + 4 * 5; // 3 + (4 * 5) = 23
Precedência de Operadores
 Qual o resultado da expressão abaixo?
 Se os operadores têm a mesma precedência 
C++ usa regras de associatividade 
(esquerda-direita ou direita-esquerda) :
 Multiplicação/Divisão/Módulo (Esquerda-Direita)
 Soma/Subtração (Esquerda-Direita)
int total = 120 / 4 * 5; // 150 ou 6
int total = 120 / 4 * 5; // 150
Operador de Divisão
 O comportamento do operador de divisão 
depende dos seus operandos:
 Se ambos são inteiros é feita a divisão inteira
 Se um ou ambos são ponto-flutuante, o resultado 
é a divisão ponto-flutuante
5 / 2 // o resultado é 2 e não 2.5
5.0 / 2 // o resultado é 2.5
5 / 2.0 // o resultado é 2.5
5.0 / 2.0 // o resultado é 2.5
Operador de Divisão
#include <iostream>
using namespace std;
int main()
{
// sempre mostra 6 casas após a vírgula
// cout.setf(ios_base::fixed, ios_base::floatfield);
cout << fixed; 
cout << "Divisão Inteira: 9/5 = " << 9/5 << endl;
cout << "Divisão Ponto-Flutuante: 9.0/5.0 = " << 9.0/5.0 << endl;
cout << "Divisão Mista: 9.0/5 = " << 9.0/5 << endl;
cout << endl;
cout << "Constantes double: 1e7/9.0 = " << 1e7/9.0 << endl;
cout << "Constantes float: 1e7f/9.0f = " << 1e7f/9.0f << endl;
system("pause");
return 0;
}
Operador de Divisão
 A saída do programa:
 O resultado é double se pelo menos um dos 
operandos é double e float caso contrário
 O tipo padrão das constantes é double
Divisão Inteira: 9/5 = 1
Divisão Ponto-Flutuante: 9.0/5.0 = 1.800000
Divisão Mista: 9.0/5 = 1.800000
Constantes double: 1e7/9.0 = 1111111.111111
Constantes float: 1e7f/9.0f = 1111111.125000
Operador Módulo
 O operador módulo (%) retorna o resto de 
uma divisão inteira
5 2
24
1
5 3
13
2
5 6
00
5
Resto da divisão
5 % 2 = 1 5 % 3 = 2 5 % 6 = 5
Operador Módulo
#include <iostream>
using namespace std;
int main()
{
const int CentavosPorReal = 100;
int valor;
cout << "Digite um valor em centavos: ";
cin >> valor;
int reais = valor / CentavosPorReal;
int centavos = valor % CentavosPorReal;
cout << valor << " centavos corresponde a\n" 
<< reais << " Reais e "
<< centavos << " centavos." << endl;
system("pause");
return 0;
}
Operador Módulo
 A saída do programa:
 Constantes devem ser inicializadas e não 
podem ter seu valor alterado no programa
Digite um valor em centavos: 210
210 centavos corresponde a
2 Reais e 10 centavos
const int CentavosPorReal = 100;
CentavosPorReal = 200; // atribuição inválida
const int CargaHoraria; // deve ser inicializado
CargaHoraria = 60; // atribuição inválida
Conversões de Tipo
 A existência de muitos tipos de dados
permite ao programador usar o que for mais 
adequado as suas necessidades
 short, int, long, long long, char, unsigned char, 
unsigned short, unsigned int, unsigned long, 
unsigned long long, float, double, long double
 Para facilitar a linguagem C++ faz muitas 
conversões automáticas de tipos
Conversões de Tipos
 Conversões automáticas são feitas:
 Em atribuições de valores à variáveis, quando o 
valor é de um tipo diferente da variável
 Em expressões, quando se combinam valores e/ou 
variáveis de tipos diferentes
int valor = 2.5; // 2.5  2
float resultado = 10; // 10  10.0
int total = 2 + 3.5 + 1; // 6.5  6
float resultado = 11/2.0; // 5.5  5.5f
Conversões de Tipos
 Conversões automáticas são feitas:
 Na passagem de argumentos para funções, 
quando os argumentos têm tipos diferentes dos 
parâmetros da função
 Para entender o resultado de alguns 
programas é preciso entender as conversões
double soma (double, double); // protótipo da função
soma(3, 5); // chamada da função: 3  3.0, 5  5.0
Conversões na Atribuição
 C++ é bastante liberal na atribuição de 
valores numéricos
 Atribuir um valor para uma variável com uma 
largura de bits maior não gera nenhum problema 
char mar = 102;
short sol = mar; // o tipo char é convertido em short
0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0
0 1 1 0 0 1 1 0 char = 8 bits
short = 16 bits
Conversões na Atribuição
 É preciso tomar cuidado com atribuições de 
valores para tipos com menor largura de bits
 Apenas os bits de mais baixa ordem são copiados 
quando o tipo de destino tem uma largura menor
short sol = 280; 
char mar = sol; // o valor armazenado é 24
0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0
0 0 0 1 1 0 0 0 char = 8 bits
short = 16 bits
Conversões na Atribuição
 Potenciais problemas de conversão
Tipo de Conversão Problema Potencial
Tipo ponto flutuante maior para tipo 
ponto flutuante menor
Ex.: double pra float
• Perda de precisão (dígitos
significativos)
• Valor pode estar fora da faixa do tipo 
alvo, e neste caso o resultado é 
indefinido
Tipo ponto flutuante para tipo 
inteiro
Ex.: double para int
• Perda da parte fracionária
• Valor pode estar fora da faixa do tipo 
alvo, e neste caso o resultado é 
indefinido
Tipo inteiro maior para tipo inteiro 
menor
Ex.: long pra short
• Valor original pode estar fora da 
faixa para o tipo alvo: apenas os bits 
de mais baixa ordem são copiados
Conversões na Atribuição
#include <iostream>
using namespace std;
int main()
{
// cout.setf(ios_base::fixed, ios_base::floatfield); 
cout << fixed;
float tres = 3; // int convertido para float
int aposta = 3.9832; // double convertido para int
int debito = 7.2E12; // resultado não definido
cout << "tres = " << tres << endl;
cout << "aposta = " << aposta << endl;
cout << "debito = " << debito << endl;
system("pause");
return 0;
}
Conversões na Atribuição
 A saída do programa:
 O valor inteiro foi convertido para float
 O valor float foi truncado (e não arredondado)
 A variável debito recebeu um valor muito grande, 
o resultado obtido está errado
tres: 3.000000
aposta: 3
debito: 1634811904
Conversões em Expressões
 O que acontece se tipos diferentes forem 
misturados em uma expressão aritmética?
 Alguns tipos são convertidos automaticamente 
sempre que eles são usados em expressões
 Alguns tipos são convertidos apenas quando 
combinados com outros tipos específicos
// val é convertido para double devido ao 2.50
float total = 2.50 * val; 
char a = 90; 
char b = 70; 
int val = a + b; // char é convertido para int
Conversões em Expressões
 Conversão automática em expressões:
 Os tipos char e short são sempre convertidos para 
int (isso inclui as versões signed e unsigned)
char ch1 = '%'; // % = 37
char ch2 = '&'; // & = 38
// char's para int e o resultado int para char
char ch = ch1 + ch2; // K = 75
short galinhas = 20; 
short patos = 35; 
// short's para int e o resultado int para short
short aves = galinhas + patos; 
Conversões em Expressões
 Quando uma operação envolve dois tipos, o 
menor é convertido para o maior
 Quando os tipos são iguais não ocorre 
conversão, mas cuidado
// o valor 5 é convertido para double
float total = 9.0 / 5;
// o valor5 é convertido para long long
long long val = 163481190409292 + 5;
// ambos os operandos são inteiros
// mas o resultado não cabe em um inteiro
long long erro = 100000000 * 2009; // -963462912
Conversões em Funções
 Os protótipos das funções controlam as 
conversões nas passagens de argumento
 Aplicam-se as mesmas regras usadas na 
atribuição de valor para variável
float soma(float, float);
float a = soma(3,4); // int  float
// o resultado da função é convertido (float  int)
int b = soma(3.0, 4.0); // double  float
float c = soma(3.0f, 4.0f); // nenhuma conversão
Type Casts
 A linguagem C++ permite ao programador 
forçar conversões de tipos
float parcial = 5.4;
int resultado = int (3.8) + int (parcial);
int total = int (parcial); // estilo C++
int total = (int) parcial; // estilo C
cout << int ('A');
cout << char (65);
long long bignum = long long (100000000) * 2009;
Declarações auto em C++11 
 C++11 introduz a possibilidade de deduzir o 
tipo a partir do valor de inicialização 
 Entretanto esta dedução automática não foi 
concebida para estes casos simples
auto n = 100; // n é int
auto x = 1.5f; // x é float
auto y = 1.3e5; // y é double
std::vector<double> vet;
std::vector<double>::iterator iv = vet.begin();
std::vector<double> vet;
auto iv = vet.begin(); 
Conclusão
 Os tipos básicos de dados tipo 
ponto-flutuante são:
 float
 double
 long double
 Valores ponto-flutuante são armazenados 
com uma mantissa e um expoente 
 O arquivo cfloat pode ser consultado para 
saber os tamanhos de cada tipo 
Conclusão
 C++ dispõem de cinco operadores 
aritméticos:
 Soma 
 Subtração
 Multiplicação
 Divisão (Inteira e Ponto-Flutuante)
 Módulo
 Conversões são feitas automaticamente mas 
também podem ser forçadas via type cast

Continue navegando