Hi,
Maybe you should study
cire's code closely. It is really quite simple - there is no overly tricky math. Perhaps the
auto
keyword is making the types more difficult to understand?
auto
in this context deduces the type from the declaration, I have annotated
cire's code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
#include <iostream>
int main()
{
auto year_length = 365.00; // double because of digits after the decimal point
auto group_size = 2u; // unsigned int - the u in the literal
for (auto j = 0; j < 40; ++j) // int
{
auto percent_all_different = 1.0; // double
for (auto i = 0u; i < group_size; ++i) // unsigned int - the u in the literal
percent_all_different *= (1 - i / year_length);
std::cout << "The probability that a group of size ";
std::cout << group_size++ << " has at least one birthday in common is ";
std::cout << (1 - percent_all_different) * 100 << "%\n";
}
}
|
About int and double: An
int
does not have a fraction part, a
double
is a number with a decimal fraction and possibly an exponent. So there are some calculations that can be done with just an
int
, and others where
double
is required.
I will mention your code just to point out some things about how the types work, but you should do something near to what
cire has. In your code a
double
type is necessary because of the division. Integer division is truncated because it can't have a fraction part. In this code if variable
i
was an
int
:
prob_not *= (i/(365));
Then one can just change the
365
to
365.0
. Because of the literal 365.0 is a
double
, and the type promotion rules, this makes the result a
double
.
prob_not *= (i/(365.0));
So the variables in the for loop could and should be integral. But there is nothing stopping one from converting variables to a double type inside the loop body.
Another really good thing to learn is the naming of your variables - make them meaningful and don't abbreviate them. Instead of
N
I would have used
ClassSize
. People have different preferences for things like upper or lower_case with underscore, PascalCase, or camelCase.Good names can make your code self documenting - the code should read like a story of what is happening. Here is a comical example of what I mean:
http://www.cplusplus.com/forum/lounge/176684/#msg872881
I like to use the same variable name in the function call and in the function definition - it reinforces the idea that they are the same thing.
With doubles, I always put numbers before and after the decimal point - it reinforces the idea that it is a double, do this:
1 2
|
double a = 1.0;
double b = 0.3;
|
Not this:
1 2
|
double a = 1;
double b = .3;
|
More modern with auto and braces:
1 2
|
auto a {1.0};
auto b {0.3};
|