probability calculator with factorial equation - c++

I have to make a code that calculates the probability of winning the lottery given the amount of numbers there are to choose from and how many you must choose. I must use the factorial equation (n!)/(k!*(n-k)!) in the code. The code itself works fine, but the equation will not compile.
//This program calculates the probability of winning the lottery
#include <iostream>
using namespace std;
double factorial(int n, int k);
int main()
{
//variables
int n;
int k;
char pa;
int chance;
double prob;
//loop
do
{
cout << "How many numbers (1-12) are there to pick from?\n" << endl;
cin >> n;
if(n>12 || n<1)
{
cout << "Invalid entry.\nHow many numbers (1-12) are there to pick from?\n";
cin >> n;
}
cout << "How many numbers must you pick to play?\n";
cin >> k;
if(k>n || k<1)
{
cout << "Invalid entry.\nHow many numbers must you pick to play?\n";
cin >> n;
}
cout << "Your chance of winning the lottery is 1 in " << chance << endl;
prob=factorial( n, k);
cout << "This is a probability of " << prob << endl;
cout << "Play again?";
cin >> pa;
} while (pa != 'n');
return 0;
}
double factorial(int n, int k)
{
double fact;
fact=(n!)/(k!*(n-k)!);
return fact;
}

There is no ! operator in C++ in the meaning of a factorial operation, and your factorial function is not calculating a factorial. (The ! operator is typically a logical NOT operator.)
This is how one would write a factorial method,
int factorial(int n) {
return (n <= 1 ? 1 : n * factorial(n - 1));
}
The method is recursive and is operating on integers - you may need to consider whether this is suitable for your task
Then your original function should be renamed along the lines of double choice(int n, int k) and use the new factorial implementation.

You cannot write n! and expect it to calculate the factorial of n.
Change fact=(n!)/(k!*(n-k)!) to fact=f(n)/(f(k)*f(n-k)), and add the following function:
unsigned long long f(int n)
{
unsigned long long res = 1;
while (n > 1)
{
res *= n;
n--;
}
return res;
}
BTW, you have several other problems within your code:
You are using variable chance without initializing it.
Function factorial does not return the probability, but the number of different choices. This is an integer value, and you might as well use unsigned long long instead of double for it. The probability is the inverse of the value (1/value), so you should change your printed message accordingly.

Related

C++ code - Error message when floating point is entered [duplicate]

I've written a program that returns the median value of a user-defined array. While I've put a few checks in my code (array size can not be negative) I keep running into one issue I simply can not fix (for clarity sake, assume strings and alphabetical characters will not be used).
All of my input values are int however the user could just as easily enter in a float. When they do this (either for size of array or entering in the element) it breaks my code. I've tried multiple things to try and catch this, but it seems like the way my program is getting the value doesn't allow for the catch in time.
#include <iostream>
using namespace std;
void sort(int * a,int n)
{
for(int i=0;i<n;++i)
for(int j=i+1;j<n;++j)
{
if(a[i]>a[j])
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}\
}
return;
}
int main()
{
int n;
int check;
int x;
cout<<"Enter length of array:";
cin>>n;
if (n < 0){
while (n < 0){
cout << "Please enter a length greater than 0" << endl;
cin >> n;
}
} else if (n % 1 != 0){
while (n % 1 != 0){
cout << "Whole numbers only! Try again" << endl;
cin >> n;
}
}
if (n == 0){
cout <<"You try to enter numbers, but there's no place to put them." << endl;
cout << ":(";
return 0;
}
int a[n];
cout<<"Enter values one by one:\n";
for(int i=0;i<n;++i){
cin >> x;
a[i] = int(x);
}
sort(a,n);
if (n % 2 == 1){
cout<<"Median is:"<<a[n/2]<<endl;
}
else{
float z = (float(a[n/2]) + float(a[(n/2)-1])) / 2;
cout << "Median is:" << z << endl;
}
return 0;
}
First thing I tried was catching the float like so
`if (n % 1 !=0){
while(n % 1 !=0){
cout << "Enter a whole number"
cin >> n
}
}`
This still broke my program. The odd thing was that I entered a float and then printed the value of n and it only showed the int value.
I tried using typeid.n() with #include <typeinfo>and comparing that to an int type to check it was the correct value, but that slipped through as well.
I tried doing an int cast, something like int(n) immediately after number was stored in n but before it went into a[n] and yet again, it still broke my code.
How can I check against float user-input and loop them until they give me an int?
You're reading into an int:
int x;
...
cin >> x;
So it will read what it can, then stop at e.g. a . and leave the rest on the stream (like if the user enters "123.4" you'll get 123 and then ".4" won't be consumed from the input stream).
Instead, you could read into a float:
float x;
...
cin >> x;
And do the appropriate math.
Alternatively you could read into a string and parse it into a float. That way you won't get stuck at letters and such either.
And the final option is to read into an int but handle any errors and skip the bad input, which is detailed at How to handle wrong data type input so I won't reproduce it here.
Which option you choose really just depends on what you want the behavior of your program to be and how strictly you want to validate input (e.g. round vs. fail if "2.5" is entered but an integer is expected, how do you want to handle "xyz" as input, etc.).

I wrote code to convert decimal fraction number to its binary equivalent. It compiles fine but when executed hangs

I wrote code to convert decimal fraction number to its binary equivalent. It compiles fine but when executed hangs. The code here prints only first four digits of the binary conversion and if the number if with more than 4 digits, it shows '...' after it. On execution it hangs. Help!
#include <iostream>
using namespace std;
int main()
{
int i, x[10];
float num;
cout << "**PROGRAM TO CONVERT DECIMAL FRACTION INTO ITS EQUIVALENT BINARY**\n";
cout << "Enter a fraction in between 0 to 1 for conversion: ";
cin >> num;
if (num>=0 && num<=1)
{
i=1;
while (num!=1.000)
{
num*=2;
x[i]=num;
num=num-x[i];
i++;
}
if (i>4)
{
cout << "The binary equivalent is 0.";
for (i=1;i<=4;i++)
{
cout << x[i];
}
cout << "...";
}
else
{
cout << "The binary equivalent is 0.";
for (i=1;i<=4;i++)
{
cout << x[i];
}
}
}
else
{
cout << "The number entered is out of range.";
}
return 0;
}
The first obstacle is the infinite while loop:
Assuming input num=0.5
after first iteration, i=1, x[0]=1, num=0.0
after second iteration, i=2, x[1]=0, num=0.0
Continue forever, i=..., x[i-]1=0, num=0.0
With nothing to break the loop.
while (num!=1.000)
{
num*=2;
x[i]=num;
num=num-x[i];
i++;
}
To fix, consider few changes. There might be other issues.
put a limit on the while loop (i<10 should be a good condition, as this is the size of the x array), or i=4, as this is the maximum output.
The break condition for the while loop should probably be 'num != 0', or even better (num > 1e-7, or other small value).
float has 23 bit in mantissa, maybe it is because you are assign x[i] with i greater than 9.
try this:
//stop when you get four bits
while (i< 5)
Original code has several issues:
1 For input num=.5 and similar (really for all values) cycle never ends (dash-o suggested fix ideas)
2 array x[10] is overflowed with undefined behavior (Edney)
3 nitpicking: 1 is not a “fraction” and better check for a range 0 <= num < 1 instead of 0 <= num <= 1(see also OP printing code; 1 could be added); we could use x[4] with 0<=i <=3
4 string could also be used (PaulMcKenzie). Really “>>” uses string processing for parsing and calculating binary equivalent from which by multiplying by 2 (left shit) and truncation fractional part the code calculates target bits. Both approaches give correct identical results; implementing by string we need to add internal to operator “>>” implementation code to parsing valid formats for floats (decimals) such as 3.14e-1, .2718, 1e-1, etc.
This fix follows OP:
#include <iostream>
using namespace std;
int main()
{
int i, x[5];
float num;
cout << "**PROGRAM TO CONVERT DECIMAL FRACTION INTO ITS EQUIVALENT BINARY**\n";
cout << "Enter a fraction in between 0 to 1 for conversion: ";
cin >> num;
if (num>=0 && num<1)
{
i=1;
while (i<=4)
{
num*=2;
x[i]=num;
num=num-x[i];
i++;
}
cout << "The binary equivalent is 0.";
for (i=1;i<=4;i++)
{
cout << x[i];
}
if (num>0)
cout << "...";
}
else
{
cout << "The number entered is out of range.";
}
return 0;
}
This code is without cycles (they are in code implementing “>>”, bitset):
#include <iostream>
#include <bitset>
using namespace std;
int main () {
const int digits = 4;
int fraction;
float num;
cout << "**PROGRAM TO CONVERT DECIMAL FRACTION INTO ITS EQUIVALENT BINARY**\n";
cout << "Enter a fraction in between 0 to 1 for conversion: ";
cin >> num;
if (num >= 0 && num < 1) {
fraction = num = num * pow (2, digits);
cout << "The binary equivalent is 0.";
cout << bitset<digits> (fraction);
if (num - fraction > 0) cout << "...";
}
else cout << "The number entered is out of range.";
}

Floats breaking my code

I've written a program that returns the median value of a user-defined array. While I've put a few checks in my code (array size can not be negative) I keep running into one issue I simply can not fix (for clarity sake, assume strings and alphabetical characters will not be used).
All of my input values are int however the user could just as easily enter in a float. When they do this (either for size of array or entering in the element) it breaks my code. I've tried multiple things to try and catch this, but it seems like the way my program is getting the value doesn't allow for the catch in time.
#include <iostream>
using namespace std;
void sort(int * a,int n)
{
for(int i=0;i<n;++i)
for(int j=i+1;j<n;++j)
{
if(a[i]>a[j])
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}\
}
return;
}
int main()
{
int n;
int check;
int x;
cout<<"Enter length of array:";
cin>>n;
if (n < 0){
while (n < 0){
cout << "Please enter a length greater than 0" << endl;
cin >> n;
}
} else if (n % 1 != 0){
while (n % 1 != 0){
cout << "Whole numbers only! Try again" << endl;
cin >> n;
}
}
if (n == 0){
cout <<"You try to enter numbers, but there's no place to put them." << endl;
cout << ":(";
return 0;
}
int a[n];
cout<<"Enter values one by one:\n";
for(int i=0;i<n;++i){
cin >> x;
a[i] = int(x);
}
sort(a,n);
if (n % 2 == 1){
cout<<"Median is:"<<a[n/2]<<endl;
}
else{
float z = (float(a[n/2]) + float(a[(n/2)-1])) / 2;
cout << "Median is:" << z << endl;
}
return 0;
}
First thing I tried was catching the float like so
`if (n % 1 !=0){
while(n % 1 !=0){
cout << "Enter a whole number"
cin >> n
}
}`
This still broke my program. The odd thing was that I entered a float and then printed the value of n and it only showed the int value.
I tried using typeid.n() with #include <typeinfo>and comparing that to an int type to check it was the correct value, but that slipped through as well.
I tried doing an int cast, something like int(n) immediately after number was stored in n but before it went into a[n] and yet again, it still broke my code.
How can I check against float user-input and loop them until they give me an int?
You're reading into an int:
int x;
...
cin >> x;
So it will read what it can, then stop at e.g. a . and leave the rest on the stream (like if the user enters "123.4" you'll get 123 and then ".4" won't be consumed from the input stream).
Instead, you could read into a float:
float x;
...
cin >> x;
And do the appropriate math.
Alternatively you could read into a string and parse it into a float. That way you won't get stuck at letters and such either.
And the final option is to read into an int but handle any errors and skip the bad input, which is detailed at How to handle wrong data type input so I won't reproduce it here.
Which option you choose really just depends on what you want the behavior of your program to be and how strictly you want to validate input (e.g. round vs. fail if "2.5" is entered but an integer is expected, how do you want to handle "xyz" as input, etc.).

What is wrong with my recursive fibonacci program?

I am unsure what the fault in my logic is. Sample output:
How many terms of the Fibonacci Sequence do you wish to compute?
1
1
1
--How many terms of the Fibonacci Sequence do you wish to compute?
5
5
5
5
5
5
5
Why is it doing this?
// Recursive Fibonacci Sequence
#include <iostream>
using namespace std;
double fib(double number);
int main(void) {
double number;
cout << "How many terms of the Fibonacci Sequence do you wish to compute?" << endl;
cin >> number;
for(int i = 0; i <= number; ++i)
cout << fib(number) << endl;
} // end main
// function fib definition
double fib(double number) {
if((number == 0) || (number == 1))
return number;
else
return fib(number - 1) + fib(number - 2);
} // end function fib
Look at your loop:
for(int i = 0; i <= number; ++i)
cout << fib(number) << endl;
Notice how the body of the loop doesn't use i... it always calls fib(number). Changing that to fib(i) will fix it.
(It's not terribly efficient, in that you'll end up recalculating values each time, but that's a separate matter. While you could put the printing in fib, that mixes the concerns of "what to do with the results" and "computing the Fibonacci sequence".)
You should just pass 'i' as the parameter in your for loop not 'number'
Make it:
for(int i = 0; i <= number; ++i)
cout << fib(i) << endl;

creating a sum function for summing only part of a vector

Obviously I need a sum function for this and accumulate will not cut it
I need to create program - a vector - with n number of elements the user can prescribe - and the sum function can only sum POSITIVE elements even though the user can enter negative elements as well...
In the computeSum function I also need to add a "success" to the whole group
computeSum (dataVec, howMany, total, sucess);
and create a parameter for people who enter - all negative numbers but want to sum them but are unable to because there are no positive numbers
if (success) {
cout << "The sum is " << total << endl;
}
else {
cerr << "Oops, you cannot add these elements.";
}
So here is what I got
#include <iostream>
#include <vector> // need this in order to use vectors in the program
using namespace std;
int main()
{
vector<double> dataVec;
double i, n, howMany, total;
cout << "How many numbers would you like to put into the vector?";
cin >> n;
dataVec.resize(n);
for(vector<double>::size_type i=0;i < n;i++)
{
cout << "Enter the numbers: \n";
cin >> dataVec[i];
}
cout << "How many POSITIVE numbers would you like to sum?";
cin >> howMany;
cout << computeSum (dataVec, howMany, total);
}
double computeSum (vector<double> &Vec, howMany, total)
{
double total =0;
for(int i=0;i < howMany;i++)
total+=Vec[i];
return total;
}
I also seem to having trouble compiling just this - computeSum() is not being understood in int main(); howMany is not being understood in computerSum(); and on a gloabl scope total() and howMany() are undeclared (I guess that would mean i would need to decalre globally???)
In fact, accumulate will “cut it”, with an appropriate functor that only regards positive values:
int sum_positive(int first, int second) {
return first + (second > 0 ? second : 0);
}
…
std::accumulate(data.begin(), data.begin() + how_many, 0, sum_positive);
Getting on my hobby horse: Boost Range Adaptors. Hits the sweet point with me
#include <boost/range/adaptors.hpp>
#include <boost/range/numeric.hpp>
bool isnatural(int i) { return i>=0; }
using namespace boost::adaptors;
int main(int argc, char** args)
{
static const int data[] = { -130, -1543, 4018, 5542, -4389, 15266, };
std::cout << "sum: " << boost::accumulate(data | filtered(isnatural), 0) << std::endl;
return 0;
}
Output:
sum: 24826
With C++11 awesomeness1 spice:
std::cout << "sum: " << boost::accumulate(data
| filtered([] (int i) { return i>=0; }), 0) << std::endl;
1: to be honest, I really hate the clumsyness of lambda syntax:
having to specify the parameter type always
having to spell out the return statement to
For this scenario, it seems to that filtered([] (i) { i>=0 })
could be figured out by the compiler. Well, perhaps in c++22 :)
Your computeSum() function must appear above your main() function in the source file for it to be in scope. Also in your computeSum() function signature you haven't given types to the howMany and total variables. I'm guessing they should be double howMany and double total?