-------------------------------------------------------------------------
 MAC-115   - Variaveis do tipo double ------- series
==========================================================================

Tipos de dados
==============

Todo valor na linguagem C está associado a um "tipo de dados"
(data type), que é caracterizado por um domínio de valores e um
conjunto de operações. Já vimos o tipo inteiro "int" (integer).

Tipo "int" -- para números inteiros
---------

O número de bits usado para respresentar um inteiro difere de
computador para computador, o que por sua vez determina qual o
maior ou menor inteiro representável. Todos os compiladores
compatíveis com o padrão ANSI devem permitir pelo menos 2 bytes (=
16 bits) para o tipo "int". Para esse total de bits os valores
possíveis varia de -32.768 a 32.767.  Para alocar mais espaço,
pode-se usar "long int".

Para fazer leitura ou imprimir, usa-se o formato %d 
(ou %wd onde w é o número de posicoes desejadas para 
 representar o inteiro em questão).  


Tipo "float"/ "double" / "long double"  -- para números em ponto-flutuante.
--------------------------------------

Na maioria das linguagens de programação, números que têm uma
parte fracionária são chamadas de "números em ponto-flutuante"
(floating-point number), que são usados para aproximar os números
reais em matemática.

Em C há 3 tipos para números em ponto-flutuante: "float",
"double" e "long double". Em alguns casos, o "long double" é igual
a "double". A precisão e o armazenamento desses tipos depende do
compilador e do computador. Para a maioria das aplicações, é
suficiente o uso do tipo "double". Na maioria dos computadores
"float" é armazenado em 4 bytes (= 32 bits), e "double" é armazenado
em 8 bytes. Neste caso, um "float" tem precisão de cerca de 6 casas
decimais enquanto um "double" tem precisão de cerca de 15 casas
decimais. No caso de "double", o intervalo varia de aprox.
10^(-308) a 10^(308).


Formatos: %f  (para float) --- para leitura/saída (declarar de acordo)
          %lf (para double) --- para leitura/saída 
          %g  (para float ou double) -- para saída 
              %.12g (especifica que é para imprimir com 12 casas decimais)
          %e  (para notacao cienfífica -- a que faz uso de potencia de 10)
             (ex: 0.123e+25 --> 0,123 x 10^(25)) 
          %E  (ex: 0.123E+25)
         
=====================================================================
Bibliotecas
===========

 Uma "biblioteca" (library) é um conjunto de ferramentas
 escritas por outros programadores que realizam operações
 específicas. Por exemplo, na biblioteca matemática (math.h)
 há várias funções matemáticas como exp(x), sin(x), cos(x),...

Assim como escrevemos 
  
  #include <stdio.h>

para fazer uso de funções de entrada/saída (input/output), 
como por exemplo scanf e printf, para fazer uso das funções 
matemáticas, escrevemos 

   #include <math.h>

Veja os 4 últimos programas.

---------------------------------------------------------

/* 
 * arquivo: eee.c
 * --------------
 * Dado n, um inteiro, eee calcula uma aproximacao para e 
 * atraves da soma dos n primeiros termos da serie
 *
 * 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + ...
 * 
 */

#include <stdio.h>

int main()
{
  int i, n;
  double s, f;
  s = 1.0, f = 1.0;

  printf("Forneca o valor de n: ");
  scanf("%d", &n);

  for (i=1; i < n; i++) {
    f = f * i;
    s = s + 1/f;
  }

  printf("e = %.20g\n", s);
  return 0;
}

============================================

/* 
 * arquivo: exp.c
 * --------------
 * Dado x (real), e n, um inteiro, exp calcula exp(x) 
 * atraves da soma dos n primeiros termos da serie
 *
 * 1 + x + x^2/2! + x^3/3! + ...
 * 
 */

#include <stdio.h>

int main()
{
  int i, n;
  double x, s = 1.0, t = 1.0; 

  printf("Forneca o valor de n: ");
  scanf("%d", &n);
  printf("Forneca o valor de x: ");
  scanf("%lf", &x);

  for (i = 1; i < n; i++) {
    t = t * x / i;
    s = s + t;
  }

  printf("exp(%g) = %.20g\n", x, s);
  return 0;
}
=====================================================
/* 
 * arquivo: exp2.c
 * ---------------
 * Dado x (real), e n, um inteiro, exp calcula exp(x) 
 * atraves da soma dos n primeiros termos da serie
 *
 * 1 + x + x^2/2! + x^3/3! + ...
 * 
 */

#include <stdio.h>
#include <math.h> /****** VEJA! ********/
                         /*** para fazer uso da funcao exp(.)***/
                         /*** da biblioteca math. **************/

int main()
{
  int i, n;
  double x, s = 1.0, t = 1.0;

  printf("Forneca o valor de n: ");
  scanf("%d", &n);
  printf("Forneca o valor de x: ");
  scanf("%lf", &x);

  for (i = 1; i < n; i++) {
    t = t * x / i;  // poderia abreviar como  t *= x / i
    s = s + t;      // poderia abreviar como  s += t
  }

  printf("exp(%g) = %.20g [nossa serie]\n", x, s);
  printf("exp(%g) = %.20g [biblioteca math]\n", x, exp(x)); /* VEJA!!*/
  return 0;
}

===========================================

/* 
 * arquivo: arctan.c
 * -----------------
 * Dado x (real), e n, um inteiro,  calcular arctan x, 
 * atraves da soma dos n primeiros termos da serie
 *
 * x - x^3 / 3 + x^5 / 5 - x^7 / 7 + ...
 * 
 */


#include <stdio.h>
#include <math.h>  // <=== para fazer o calculo de arctan(x) usando a funcao 
                  //   atan(.) da biblioteca math. Veja: é atan e não arctan o
                  //   nome da funcao. Veja o ultimo printf.
int main()
{
  int i, n;
  double x, s, potx;

  printf("Forneca o valor de n: ");
  scanf("%d", &n);
  printf("Forneca o valor de x: ");
  scanf("%lf", &x);

  s = potx = x;

  for (i = 1; i < n; i++) {
    potx = - potx *  x * x;
    s = s +  potx / (2 * i + 1);
  }

  printf("arctan(%g) = %.20g\n", x, s);
  printf("Usando a funcao atan(.) ja' disponivel: arctan(%g) = %g\n", x, atan(x));
  return 0;
}


=======================================================================
   Variaçoes sobre o mesmo tema -- calculo sem fixar o numero de termos
   ============================

/* 
 * arquivo: exp2epsilon.c
 * ----------------------
 * Dado x e epsilon (reais) e n, um inteiro, exp calcula exp(x) 
 * atraves da soma dos termos da serie 
 *
 * 1 + x + x^2/2! + x^3/3! + ...
 *
 * ate o valor absoluto da parcela se tornar <= epsilon.
 * Paramos quando encontramos um tal termo.
 */

#include <stdio.h>
#include <math.h> 

int main()
{
  int i;
  double x, epsilon, s = 1.0, t = 1.0;

  printf("Forneca o valor de epsilon: ");
  scanf("%lf", & epsilon);
  printf("Forneca o valor de x: ");
  scanf("%lf", &x);

  i = 1;
  while (t > epsilon || t < -epsilon) {
    t *= x / i;  // forma simplificada de t = t * x / i //
    s += t;      // forma simplificada de s = s + t //
    i++;
  }

  printf("exp(%g) = %.20g [nossa serie]\n", x, s);
  printf("exp(%g) = %.20g [biblioteca math]\n", x, exp(x));
  return 0;
}

---------------------------------------------------------------

/* 
 * arquivo: exp2indif3.c
 * ---------------------
 * Dado numero real x, este programa calcula exp(x) 
 * atraves da soma dos termos da serie
 *
 * 1 + x + x^2/2! + x^3/3! + ...
 *
 * A soma e' feita ate que a soma de um termo nao faca mais
 * diferenca.  Isto e', ate' que  somar novos termos fique
 * "indiferente".
 */

#include <stdio.h>
#include <math.h> 

int main()
{
  int i;
  double x, s = 0.0, t = 1.0, tmp;

  printf("Forneca o valor de x: ");
  scanf("%lf", &x);

  tmp = t;
  i = 1;
  while (s != tmp) {
    s = tmp;
    t = t *  x / i;
    tmp = s + t;
    i++;
  }

  printf("exp(%g) = %.20g [nossa serie]\n", x, s);
  printf("exp(%g) = %.20g [biblioteca math]\n", x, exp(x));
  return 0;
}