#include <iostream>
#include <ctime>
#include <cmath>
#include <fstream>


using namespace std;


inline double unif_rand() {
	return (rand()+0.5)/(RAND_MAX+1.0);
}

double gaussBM() {
	static double r,theta;//une variable "static", dans une fonction utilisée plusieurs fois dans l'exécution d'un programme, a la propriété de rester en mémoire d'une fois sur l'autre. Ici, r et theta, à la première itération de gaussBM, n'existent pas : ils sont alors calculés et définis. De même, r_et_theta_ok est défini comme valant false, puis, dans l'itération, est transformé en true. A l'itération suivante (la deuxième), r_et_theta_ok valant true, on ne recalcule pas r et theta. Par contre, r_et_theta_ok devient false, donc à la troisième itération, on recalcule (et redéfinit) r et theta...
	static bool r_et_theta_ok;
	
	if (r_et_theta_ok) {r_et_theta_ok = false; return r*sin(theta);}//attention, ne pas écrire {return r*sin(theta); r_et_theta_ok = false;} car dans ce cas, la deuxième instruction, placée après "return", ne sera pas exécutée 
	else {	theta=2*M_PI*unif_rand();
	r=sqrt(-2*log(unif_rand()));
	r_et_theta_ok = true;
	return r*cos(theta);
	}
}


int main() {
	int n;
	bool affichage;
	cout<<"affichage sur la console (=1) ou enregistrement (=0) dans echant.dat ?"<<endl;
	cin>>affichage;
	cout<<"n ?"<<endl;
	cin>>n;
	srand(time(0));//on n'oublie pas d'initialiser la graine de rand
	rand();//on laisse passer la première valeur, qui n'est pas aléatoire
	if (affichage) {for(int i=0; (i<n && i<20) ;++i) {
		cout<<gaussBM()<<endl;}}
	else {
		cout<<"calcul en cours...";
		ofstream fichier("echant.dat");
		for(int i=0; i<n;++i) {fichier<<gaussBM()<<endl;}
		fichier.close();}
	cout<<"fini !"<<endl;
	return 0;
}