random data generator for C

Let’s consider whether this random number generator is ‘good’ or not.

random1 = rand() % 2;

There are two problems with this approach. One is that the low order bits of the random number generator are not particularly random, so neither with random1 be. On my machine, there’s a slight but measurable bias toward 0 with that. The second problem is that it’s not thread safe because rand stores hidden state. A better solution, if your compiler and library supports it, would be to use the C++11 `std::uniform_int_distribution. It looks complex, but it’s actually pretty easy to use. One way to do that (from Stroustrup) is like this:

int rand_int(int low, int high)
{
  static std::default_random_engine re {};
  usingDist = std::uniform_int_distribution<int>;
  staticDist uid {};
  return uid(re,Dist::param_type{low,high});
}

This still stores state, but at least the distribution is correct.

Source: http://codereview.stackexchange.com/questions/49614/text-based-adventure-game-with-too-many-conditional-statements

Program w C++ do symulacji spłat kredytu, harmonogram spłat kredytu

Jako że zadano mi napisanie programu finansowego jako cześć interview, postanowiłem podzielić się swoją twórczością. Raty kredytu dzielą się na dwie kategorie, raty malejące i raty stałe. Program kompiluje się bez problemu w Dev-CPP, natomiast aby uzyskać polskie znaki po uruchomieniu, korzystamy z komendy “chcp 1250”. Program pyta użytkownika o parametry kredytu, następnie sam tworzy (rysuje) tabelkę ze scenariuszem spłat.


#include <iostream>
#include <string>
#include <iomanip>
#include <math.h>

using namespace std;

char KWOTA_KREDYTU[18], ILOSC_RAT[3], STOPA_PROCENTOWA[22], TYP_SPLATY[2];
int I_KWOTA_KREDYTU, I_ILOSC_RAT, I_STOPA_PROCENTOWA, I_TYP_SPLATY;

/**
* DODAWANIE
*/
double add(double n1, double n2){
return n1 + n2;
}
/**
* ODEJMOWANIE
*/
double sub(double n1, double n2){
return n1 - n2;
}
/**
* MNOŻENIE
*/
double mul(double n1, double n2){
return n1 * n2;
}
/**
* DZIELENIE
*/
double div(double n1, double n2){
if(n2 == 0) cout << "Ostrzeżenie: dzielenie przez zero. " << endl;
return n1 / n2;
}
double calc(double(*f)(double,double), double n1, double n2, char op){
cout << n1 << " " << op << " " << n2 << " = " << f(n1,n2);
}

void __s_kredyt(){
int a = 0;
char* tab_input = new char[2];

char temp;
do{
temp = cin.get();
if(!isprint(temp)) temp = '';
*(tab_input + a++) = temp;
*(tab_input + a) = '';
char* tab_input_temp = new char[a + 1];
strcpy(tab_input_temp,tab_input);
delete [] tab_input;
tab_input = new char[a + 2];
strcpy(tab_input,tab_input_temp);
delete [] tab_input_temp;
}while(temp != '');

cout << "\nWPROWADZONO: " << tab_input
<< " , czy o taką kwotę Ci chodziło (T/N)?\n";
}

char c;

void __ns_kredyt(){
cin >> I_KWOTA_KREDYTU;
cout << "\nWPROWADZONO: " << I_KWOTA_KREDYTU
<< " , czy o taką kwotę Ci chodziło (T/N)?\n\n";
cin >> c;
c = toupper(c);
while (c != 'T'){
cout << "\nWprowadź ponownie kwotę:\n\n";
cin >> I_KWOTA_KREDYTU;
cout << "\nWPROWADZONO: " << I_KWOTA_KREDYTU
<< " , czy o taką kwotę Ci chodziło (T/N)?\n\n";
cin >> c;
}
}

void __ns_raty(){
cin >> I_ILOSC_RAT;
cout << "\nWPROWADZONO: " << I_ILOSC_RAT
<< " , czy o taką liczbę rat Ci chodziło (T/N)?\n\n";
cin >> c;
c = toupper(c);
while (c != 'T'){
cout << "\nWprowadź ponownie liczbę rat:\n\n";
cin >> I_KWOTA_KREDYTU;
cout << "\nWPROWADZONO: " << I_KWOTA_KREDYTU
<< " , czy o taką liczbę rat Ci chodziło (T/N)?\n\n";
cin >> c;
}
}

void __ns_stopa(){
cin >> I_STOPA_PROCENTOWA;
cout << "\nWPROWADZONO: " << I_STOPA_PROCENTOWA << "% "
<< " , czy o taką stopę Ci chodziło (T/N)?\n\n";
cin >> c;
c = toupper(c);
while (c != 'T'){
cout << "\nWprowadź ponownie stopę procentową:\n\n";
cin >> I_STOPA_PROCENTOWA;
cout << "\nWPROWADZONO: " << I_STOPA_PROCENTOWA << "% "
<< " , czy o taką liczbę procentową Ci chodziło (T/N)?\n\n";
cin >> c;
}
}

void __ns_typ(){
string SI_TYP_SPLATY;
cin >> SI_TYP_SPLATY;
I_TYP_SPLATY = -1;
transform(SI_TYP_SPLATY.begin(), SI_TYP_SPLATY.end(),
SI_TYP_SPLATY.begin(), ::toupper);
if ( SI_TYP_SPLATY.compare("RS") == 0 ) I_TYP_SPLATY = 1;
if ( SI_TYP_SPLATY.compare("RM") == 0 ) I_TYP_SPLATY = 0;
cout << "\nWPROWADZONO: " << SI_TYP_SPLATY
<< " , czy na pewno nie chcesz wybrać innego sposobu spłaty (T/N)?\n\n";
cin >> c;
c = toupper(c);
while (c != 'T'){
cout << "\nWprowadź ponownie sposób spłaty kredytu:\n\n";
cin >> SI_TYP_SPLATY;
I_TYP_SPLATY = -1;
transform(SI_TYP_SPLATY.begin(), SI_TYP_SPLATY.end(),
SI_TYP_SPLATY.begin(), ::toupper);
if ( SI_TYP_SPLATY.compare("RS") == 0 ) I_TYP_SPLATY = 1;
if ( SI_TYP_SPLATY.compare("RM") == 0 ) I_TYP_SPLATY = 0;
cout << "\nWPROWADZONO: " << SI_TYP_SPLATY
<< " , czy o taki sposób Ci chodziło (T/N)?\n\n";
cin >> c;
}
}

void ___print_header(){
// print table header
cout << setw(10) << "Nr raty" << setw(20)
<< "Wysokość spłaty" << setw(15)
<< "Odsetki"
<< setw(20) << "Część kapitałowa" << setw(20)
<< "Kapitał do spłaty" << endl << endl;
}

void ___print_data(){

}

char* splaty, odsetki, raty, saldo;

double liczrate(double kredyt, double oprocentowanie , int liczba_rat){
double q1 = oprocentowanie / 12;
double q2 = 1;

for (int i = 0 ; i < liczba_rat ; i++){
q2 = q2 * (1 + q1);
}
return kredyt * q2 * q1 /(q2 - 1);
}

/**
*
*/
void calculate(int a /*KWOTA KREDYTU*/, int b /*RATY W MIESIACACH*/, int c /*STOPA PROCENTOWA*/){
int nr_raty = 0;
double s = c * 0.01;
double saldo = a;

double ll = liczrate(a, s, b);
double kapital = a;

cout.precision(2);

for(int i = 0 ; i < b ; i++){
double odsetki = kapital * s / 12;
double czesc = ll - odsetki;
kapital = kapital - ll + odsetki;
//cout << ++nr_raty << " " << d1 << " " << d3 << " " << d2 << " " << saldo << endl;
cout << setw(10) << fixed << ++nr_raty ; cout << setw(20) << fixed << ll ; cout << setw(15) << fixed << odsetki ;
cout << setw(20) << fixed << czesc ; cout << setw(20) << fixed << kapital << endl;
}
}

/**
*
*/
void calculate_decreasing(int a /*KWOTA KREDYTU*/, int b /*RATY W MIESIACACH*/, int c /*STOPA PROCENTOWA*/){
int nr_raty = 0;

double s = c * 0.01;
double saldo = a;

cout.precision(2);

for(int i = 0 ; i < b ; i++){
//miesieczna spłata
double d1 = (( ( (saldo * s) * ( b / 12 ) ) + a) / b);
//rata kapitalowa
double d2 = ( a / b);
//odestki
double d3 = ( d1 - d2 );
//saldo
saldo -= d2;

//cout << ++nr_raty << " " << d1 << " " << d3 << " " << d2 << " " << saldo << endl;
cout << setw(10) << fixed << ++nr_raty ; cout << setw(20) << fixed << d1 ; cout << setw(15) << fixed << d3 ;
cout << setw(20) << fixed << d2 ; cout << setw(20) << fixed << saldo << endl;
}
}

/******************************************************************************/
int main(){

cout << "Kwota kredytu\n";
cout << " * Środki pieniężne oddane do dyspozycji Kredytobiorcy przez " <<
"bank na warunkach wyszczególnionych w umowie kredytowej.\n";
cout << "Proszę podaj kwotę kredytu, o jaką się ubiegasz [200000]:\n\n";
__ns_kredyt();

cout << "\nIlość rat miesięcznych\nNa ile rat rozłożyć kredyt:\n";
cout << " * Okres na jaki została zawarta umowa kredytowa pomiędzy Kredytobiorcą a bankiem\n";
cout << "Proszę podaj ilość rat w miesiącach [12]:\n\n";
__ns_raty();

cout << "\nStopa procentowa:\n\nIle wynosi stopa procentowa?:\n";
cout << " * Oprocentowanie podawane przez bank, jest to stopa odsetek od" <<
" kredytu przy spłacie jednorazowej na koniec okresu rocznego.\n";
cout << "Proszę podaj stopę procentową [20]%:\n\n";
__ns_stopa();

cout << "\nTyp spłaty (rata stała/rata malejąca):\n\nW jaki sposób będzie spłacany kredyt?:\n\n";
cout << " * Każda kolejna rata kredytu jest mniejsza, obciążenie na początku spłaty " <<
"kredytu jest najwyższe. Odsetki naliczane są od równomiernie spłacanego kapitału" <<
" dlatego w miarę upływu czasu są coraz mniejsze\n";
cout << "Proszę podaj typ spłaty [RS/RM]:\n\n";
__ns_typ();

cout << "Harmonogram spłaty: " << endl << endl;
___print_header();

if (I_TYP_SPLATY == 1) calculate(I_KWOTA_KREDYTU, I_ILOSC_RAT, I_STOPA_PROCENTOWA); else
if (I_TYP_SPLATY == 0) calculate_decreasing(I_KWOTA_KREDYTU, I_ILOSC_RAT, I_STOPA_PROCENTOWA); else
cout << "błąd...";

___print_data();

system("pause");

}