# [C++] Problème bizare

## TrizoLakai

Bonjour  :Smile: 

Voila mon petit programme : 

```
#include <iostream>

using namespace std;

int main(int argc, char *argv[]){

   int n = atoi(argv[1]);

   double S,x;

   S = 1; x = 1;

   for(int i = 1; i < (n+1); ++i){

      x /= double(n);

      S += x;

   }

   cout << "S = " << S << endl;

   return 0;

}
```

Donc comme vous pouvez le remarquer il n'y a que de des somme sur S et x est toujours positif. Ce pendant quand je fais tourner la boucle 12 fois, S ressort plus grand que lorsque que je fais tourner la boucle 14 fois. Ce qui est illogique : 

 *Quote:*   

> 
> 
> trizolakai@Athlou ~ $ ./E 14
> 
> S = 1.07692
> ...

 

Merci de bien vouloir m'aider.

----------

## SanKuKai

Salut.

Je vais peut-être dire des bêtises mais je ne trouve pas que c'est illogique.

Dans le premier cas (n=14) le dénominateur des termes de ta somme est plus grand que dans le second cas (n=12).

Donc même s'il y plus d'itérations, c'est pas illogique que tu aies un résultat plus petit dans le premier cas.

----------

## Temet

+1, pas illogique non plus  :Smile: 

----------

## kopp

sankukai + 1

Ton dénonimateur change, et 1/12^5 est déjà deux fois plus grand que 1/14^5, donc je te laisse imaginer à la puissance 10... les derniers termes pour 14 sont largement négligeable devant les derniers pour 12

Edit : au passage, ceci calcule les n termes d'une série géométrique de raison 1/n. Le résultat vaut alors (1-1/n^n)/(1-1/n) où n est la valeur entrée à ton programme.

La limite de cette fonction est 1, et on peut s'amuser à montrer qu'elle est décroissante si tu as envie, mais personnellement, ça me tente pas.

Des infos sur les séries géométriques:

http://fr.wikipedia.org/wiki/S%C3%A9rie_g%C3%A9om%C3%A9trique

----------

## Temet

Roh, une petite récurrence, j'ai pas fait ça depuis tellement d'années! ^^

----------

## kopp

Temet, une récurrence ?

Pour montrer le résultat peut-être, mais bon, ce genre de truc, ça se démontre plus ça s'utilise  :Wink: 

----------

## _droop_

Salut,

il me semble que tu calcules (désolé par la présentation), sum (k = 0 ; k=n ; (1/n)^k).

C'est une série géomètrique de raison 1/n. On peut calculer directement sa valeur par la formule (1-(1/n)^(n+1))/(1-(1/n)) (pour n>1).

Ca a l'air d'être décroissant et de tendre vers 1 (trivial). Donc pas de bizarrerie   :Very Happy: 

edit : la décroissance a l'air dûr à démontrer par contre...Last edited by _droop_ on Thu Nov 23, 2006 5:26 pm; edited 1 time in total

----------

## geekounet

Je m'attendais à de la prog pure, et faut que ça parle de maths ... j'en ai déjà bien assez à l'iut   :Crying or Very sad:   ...

----------

## TrizoLakai

Je pense toujours que c'est illogique.

Certe X décroit, mais S c'est la somme de 1 et de tout ces termes X, si X décroit il ne reste pas moins que X est positif et donc S ne peut que grandir non ? Et le problème surviens plus tot. 

Voici mon programme pour débuguer : 

```
#include <iostream>

using namespace std;

int main(int argc, char *argv[]){

   int n = atoi(argv[1]);

   double S,x;

   S = 1; x = 1;

   for(int i = 1; i < (n+1); ++i){

      x /= double(n);

      S += x;

      cout << i << " : x = " << x << " et S = " << S << endl;

   }

   cout << "S = " << S << endl;

   return 0;

}
```

Et la sortie avec n = 14 : 

 *Quote:*   

> trizolakai@Athlou ~ $ ./E 14
> 
> 1 : x = 0.0714286 et S = 1.07143
> 
> 2 : x = 0.00510204 et S = 1.07653
> ...

 

Et vous remarquez que ça ne change pas de valeur, et pourtant quand je fais ./E 12 ça me donne une valeur différente et plus grande.

----------

## YetiBarBar

 *TrizoLakai wrote:*   

> 
> 
> 		x /= double(n);
> 
> 

 

Le résultat est logique mais je pense que tu voulais plutôt calculer

```
x /= double(i)
```

 et la ta suite est bien croissante

----------

## YetiBarBar

 *YetiBarBar wrote:*   

>  *TrizoLakai wrote:*   
> 
> 		x /= double(n);
> 
>  
> ...

 

EDIT :

Pour le moment, tu as

```
x=(1/n)^i
```

et plus n est grand, plus x est petit et donc plus la somme est petite

----------

## TrizoLakai

Non c'est bien x /= double(n), mais i fois.

----------

## YetiBarBar

Dans ce cas droop a raison avec sa formule mais je me rappelle plus comment on démontre la décroissance ...

----------

## TrizoLakai

J'ai bien compris que x est décroissant, mais S reste croissant.

----------

## YetiBarBar

 *TrizoLakai wrote:*   

> J'ai bien compris que x est décroissant, mais S reste croissant.

 

Justement,

S= (1-(1/n)^(n+1))/(1-1/n) ou une formule du genre. Avec cette formule, tu pourrais te convaincre que S décroit aussi ...

----------

## Magic Banana

Il me semble que le cast se fait en mettant le type entre parenthèse. Je ne sais pas si c'est cela qui te pose un problème mais bon... voilà ce que j'écrirais (désolé je l'ai reformaté à ma façon) :

```
#include <iostream>

using namespace std;

int main(int argc, char *argv[])

{

  double n = (double)atoi(argv[1]);

  

  double S = 1;

  double x = 1;

  

  for(int i = 1; i < (n+1); ++i)

    {

      x /= n;

      S += x;

      cout << i << " : x = " << x << " et S = " << S << endl;

    }

  

  

  cout << "S = " << S << endl;

  return 0;

}
```

Note de plus que je fais le cast avant d'entrer dans la boucle tant qu'à faire...

----------

## Darkael

TrizoLakai, tu confonds la croissance selon n avec la croissance selon i (dans ton programme) à n fixé.

----------

## Magic Banana

Je ne vous suis pas. Regardez son programme : x est positif au départ et ai toujours divisé par quelque chose de positif donc deumeure positif. À chaque itération il ajoute un de ces x à S qui devrait donc croître...

----------

## Enlight

Oui mais les nombres qu'il ajoute décroissent de manière exponentielle, alors que le nombre d'itération croit de manière linéaire.

Le mieux ce serait qu'il nous pose l'algo brievement ou le problème mathématique en soit.

----------

## kopp

Par rapport à ton programme, le résultat est tout à fait logique ! 

D'ailleurs si tu regardes les valeurs ressorties de x, à partir de la 6eme itération, c'est de l'ordre de 10^-6, ce qui est plus petit que la précision du résultat affiché par S, d'où le fait que S ne semble plus changer. Tu rajoutes des quantités qui deviennent infinitésimal par rapport à ton résultat.

Edit: démonstration de la décroissance. Appelons s(n)  la fonction définie pour n>1 correspondant au résultat de la somme, donné par s(n)=(1-1/n^n)/(1-1/n)

On l'assume a valeur réelle. La somme ne peut pas être calculée si n n'est pas entier, mais l'expression du résultat est valide.

On dérive donc s(n) par rapport à n.

rappel : dérivée de u/v = (u'v - uv')/v²

on ne s'occupe pas du dénominateur qui sera de toute façon positif.

```
u = 1-1/n^n = 1 - exp(n*ln(1/n))

u' = - (-n*ln(n))' * exp(n*ln(1/n)) =  [ln(n) + n*1/n]*exp(...) 

v = 1 - 1/n 

v'= 1/n²

u'v - uv' = [ln(n) + 1]* exp(n*ln(1/n)) * (1-1/n) - 1/n²*(1-1/n^n)

```

on factorise par (1-1/n): 

```
u'v - uv' = (1-1/n) * (1/n^n * [ln(n) + 1] - 1 / n² * (1 + 1/n + 1/n² + ... + 1/n^(n-1)))
```

Ce qui nous intéresse, c'est le signe de 

```
A = 1/n^n * [ln(n) + 1] - 1 / n² * (1 + 1/n + 1/n² + ... + 1/n^(n-1))
```

on multiplie par n^n, ce qui ne changera pas le signe

```
A*n^n = 1 + ln(n) - (1 + n + n² + ... + n^(n-2) + 1/n)
```

Or on sait que pour tout n>=0, n>=1+ln(n) donc on a  

```
1 + ln(n) - (1 + n + n² + ... + n^(n-2) + 1/n) <= 0
```

LA dérivée est négative, la fonction est donc décroissante, ie s(n)>s(n+1)

CQFDLast edited by kopp on Thu Nov 23, 2006 7:44 pm; edited 1 time in total

----------

## SanKuKai

J'ai rédigé une petite démo à l'arrache pour montrer que la suite des sommes est bien décroissante.

(Oui j'ai du temps à perdre...  :Laughing:  )

----------

## kopp

Et merde, me suis fait chier à rédiger la démo façon analyse pour rien tiens  :Smile: 

Bon, bah voilà deux démo pour le prix d'une.

----------

## TrizoLakai

Alors je fais ce programme parce que le prof de maths d'un copain a dis qu'on pouvais calculer une aproximation de e avec un algorithme du genre : 

 *Quote:*   

> entrer n
> 
> S<- 1<- 1
> 
> pour i de 1 à n
> ...

 

Mais j'ai que ça. Alors j'ai essayé et il aparait que ça ne fonctionne pas. Je regarderais les démo demain, là j'ai a bosser :/

----------

## Enlight

Bon c'est pas tout ça, on va installer le paypal sur FGO, non?

----------

## kopp

Il y a une erreur dans ton algo. L'algo correct serait :

 *approximation de e wrote:*   

> entrer n
> 
> S<- 1<- 1
> 
> pour i de 1 à n
> ...

 

afficher S

Il faut diviser par i  et pas par n

Cela vient du fait que exp(x) peut s'écrire somme de n allant de 0 à l'infini de (x^n)/n! (ou n! est la factorielle de n)

pour e = exp(1) on a donc la somme des 1/n! et comme n! tant très vite vers l'infini (il y la formule de stirling qui donne l'apparence de n! lorsque n est très grand), en quelque itérations, les termes à rajouter devienne négligeable par rapport à la précision de ton calcul. (ex 10! = 3628800)

----------

## truc

de mémoire, la série pour obtenir e c'est plus 

Som de x^n/!n pour x=1

donc je pense que tu as les mauvaises variables, ça serait plutôt 

for(int i = 1; i < (n+1); ++i){

      x /= double(i);

      S += x ; 

j'me trompe?

----------

## kopp

truc: j't'ai grillé !!! et toc :p

----------

## truc

zut alors en haut de la deuxième page, je n'ai rien vu :s  :Laughing: 

----------

## YetiBarBar

Par contre, je vote pour un changement de titre :

Remplacer : 

```
[C++] Problèmes bizarres
```

Par :

```
[Maths] Approximation de e en C++
```

(et avec un [Résolu] ce serait encore mieux ....

----------

## Ey

 *YetiBarBar wrote:*   

> Par contre, je vote pour un changement de titre :
> 
> Remplacer : 
> 
> ```
> ...

 

Ca n'a absolument rien a voir avec du C++, c'est des maths tout ce qu'il y a de plus basiques...

Au pire un titre du genre

[MEGA HORS SUJET]Maths - série convergeant vers e

----------

## YetiBarBar

 *Ey wrote:*   

> Ca n'a absolument rien a voir avec du C++, c'est des maths tout ce qu'il y a de plus basiques...
> 
> Au pire un titre du genre
> 
> [MEGA HORS SUJET]Maths - série convergeant vers e

 

Faut pas être méchant non plus, il a écrit un code en C++ .... (si si, il utlise cout et le for(int i = 1; ... qui sont interdits en C)

Maintenant, on peut chipoter en mettre Algorithmique ....

----------

## Ey

C'est pas de l'algorithmique c'est juste le développement limité de exp(x) en 1. Alors oui c'est écrit en C++ la belle affaire, mais bon il aurait très bien pu écrire ça en Mapple ça aurait rien changé.

PS : [EDITED] faut que j'ailles me coucher moi... je racontes de la merde...Last edited by Ey on Thu Nov 23, 2006 8:49 pm; edited 2 times in total

----------

## kopp

hé Ey, pète un coup, relache la pression là  :Smile: 

----------

## TrizoLakai

Je propose un sondage pour choisir un titre.

Bon merci pour l'algorithme. Maintenant il faut que je trouve comment faire en sorte que cout sorte plus de virgule, j'avais vu ça un jour, google ? Petit canaillou, je viens te chercher !

----------

## geekounet

 *Ey wrote:*   

> C'est pas de l'algorithmique c'est juste le développement limité de exp(x) en 1. Alors oui c'est écrit en C++ la belle affaire, mais bon il aurait très bien pu écrire ça en Mapple ça aurait rien changé.
> 
> PS : [EDITED] faut que j'ailles me coucher moi... je racontes de la merde...

 

Mapple sapucépalibre !  :Laughing:  (pis c'est la galère à utiliser, surtout quand ça plante le mac en plein milieu du tp ...)

Et les maths saymal aussi ! ^^

Sur ce, moi aussi je dis n'importe quoi tout en étant off dans le off, donc je vais me coucher aussi ^^

----------

## kopp

tut tut tut ! Pour maple je suis d'accord (deux ans a en fair een version 4 sur des P133, ça vous calme un geek, je vous le dis !)

Par contre, les maths, c'est pas le mal ! C'est pas parce que tu es nul avec tes matrices que hein... :p

----------

## Enlight

 *TrizoLakai wrote:*   

> Je propose un sondage pour choisir un titre.
> 
> Bon merci pour l'algorithme. Maintenant il faut que je trouve comment faire en sorte que cout sorte plus de virgule, j'avais vu ça un jour, google ? Petit canaillou, je viens te chercher !

 

un float? pis tu pourras compiler avec ou sans march=$ton_arch et mfpmath={387,sse} et benchmarker ^_^

----------

## _droop_

Merci kopp pour la dérivé...

----------

## kopp

_droop_ : mais de rien mon grand ! j'avais des  projets à faire, alors autant m'amuser à faire des dérivées à la noix  :Smile: 

J'avoue que la démo de Sankukai n'est pas mal du tout non plus et surtout beaucoup plus simple  :Smile: 

----------

