Can't Generate Full Range of Random for Integers - c++

I am trying to generate a file of 10000 integers between 0 and 100 000 so I can do a MergeSort on them later.
When I generate the file using fstream, I never get an integer over 32760.
The following method generates the file and then reads it back and checks for any integer over 32750. I usually get between 3-5 integers between 32750 and 32760. Why does this happen and how can I fix it? Is it a seed problem or the actual use of the Random function?
// sizeOfArray = 10000
void generateFile() {
ofstream fout("unsorted.txt");
srand(time(NULL));
// Generating the file
int num;
for(int i = 0; i < sizeOfArray; i++) {
num = rand() % 100000;
if(i < sizeOfArray-1)
//fout << i+1 << ": " << num << endl;
fout << num << endl;
else
//fout << i+1 << ": " << num;
fout << num;
}
// Reading the File Back
ifstream fin("unsorted.txt");
for(int i = 0; i < sizeOfArray; i++) {
fin >> num;
if(num > 32750)
cout << num << endl;
}
cin.get();
}
SOLVED
Using the answer provided below I generated the file 500 times
and the highest Integer I received was 99931.

The highest random value that you can get from rand() is RAND_MAX, a library-dependent constant. In your case, it appears to be set to 2^15-1, the highest positive number that fits in a signed 16-bit integer.
When you need to generate numbers that are larger than RAND_MAX, call rand() several times, each time multiplying by RAND_MAX. For example, in your case the following code should work (I am assuming that your int has 32 bits):
num = rand();
num *= RAND_MAX;
num += rand();
num %= 100000;
Note that merely adding three random numbers together to get the desired range will not produce the same random distribution as multiply and add approach.

You can use one of the new random number generators introduced with C++11 to get a larger range: http://en.cppreference.com/w/cpp/numeric/random
If you don't have C++11 you can also get it from Boost: http://www.boost.org/doc/libs/1_53_0/doc/html/boost_random.html

Depends on what you are using: http://www.cplusplus.com/reference/cstdlib/RAND_MAX/

Related

C++ 2 dice rolling 10 million times BEGINNER

I am trying to create a program that will roll 2 dice 10 million times, and output how many times each number is rolled. Along with this, I am tasked with creating a histogram (*=2000) for the outputs.
Here is what I have so far.
/*
Creating a program that counts outcomes of two dice rolls, then show a
histogram of the outcomes.
Section 1 : Simulate ten million times rolls of two dice, while counting
outcomes. (Hint: Use an array of size 13.)
Section 2 : Show the outcome, the numbers of outcomes, and the histogram
(one * designates 20000). Your output must align properly.
*/
#include <iostream>
#include <iomanip>
#include <ctime>
using namespace std;
int main()
{
int i, j, ary[13] = {};
cout << "Please enter the random number seed.";
cin >> j;
srand(j);
for (i = 0; i < 10000000; i++)
ary[die() + die()]++;
for (i = 2; i <= 12; i++)
{
cout << setw(3) << i << " : " << setw(6) << ary[i] << " : ";
for (j = 0; j < ary[i]; j += 2000)
cout << "*";
cout << endl;
}
return 0;
}
EXAMPLE OUTPUT: https://imgur.com/a/tETCj4O
I know I need to do something with rand() % 6 + 1; in the beginning of the program. I feel like I am close to being complete but missing key points! I also realize I have not defnied die() in my ary[]
I recommend creating random seeds from high precision timers such as std::chrono::high_resolution_clock. Then they are not dependent on the user and are actually random. Create the seed always before calling std::rand.
#include <chrono>
auto time = std::chrono::high_resolution_clock::now();
auto seed = std::chrono::duration_cast<std::chrono::milliseconds>(time);
std::srand(seed)
Millisecond precision makes the seed usually unique enough but if the seed is required close to 1000 times a second then i recommend using nanosecond or microsecond precision to be really random.
Best would be to create a function that creates the random seed using high precision timer and the random value and finally makes sure the return value is between 0 and 5 (for 6 sided dice).

Iterating primes using mpz_nextprime

In C++, I want to print the first n prime numbers (for this example let's assume n=1000).
In order to do this, I've found mpz_nextprime from the GMP library.
I'd assume you use it like this
int n = 2;
for(int i = 0; i < 1000; i++) {
n = mpz_nextprime(n);
cout << n << endl;
}
but this doesnt compile as mpz_nextprime takes two mpz_t arguments.
How can you use mpz_nextprime in this context?
The reason for mpz_nextprime using mpz_t instead of normal integer types like int or long is that after a certain point the prime numbers will be too large to be representable in a int or long.
Here's a snippet of code to print all up to the 1000th prime number:
#include <gmp.h>
int main() {
mpz_t n;
mpz_init(n);
mpz_set_ui(n, 2);
for (size_t i = 0; i < 1000; i++) { // first 1000 primes
mpz_nextprime(n, n);
cout << "The " << (i + 1) << "th " << " prime is " << mpz_get_ui(n) << endl;
}
}
Note that this code will only work up to a certain prime number because in order to print it, we convert it to an unsigned int using mpz_get_ui here.
If you want to print larger prime numbers, use mpz_get_str (but don't forget to free() the string if you use NULL as first parameter).

The system file cannot be specified

I have been trying to output a code for a project, and have tried going through some of the other questions to try resolving the error I am getting which is listed in the title, however I am not getting anywhere with it. Please be as specific as possible, I'm a novice with coding and only know some C++
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
//Initialize Variables for initial Lattice
int Size = 0;
float Density = 0.0;
//Input Desired Lattice Size
std::cout << "How large do you want the square lattice to be? "; cin << Size;
//Input Desired Density
std::cout << "What density would you like to test for Percolation? "; cin << Density;
//Construct Matrix
float Lattice[Size][Size];
for (int i = 0; i < Size; ++i)
{
for (int j=0; j<Size; ++j)
{
Lattice[i][j] = float((int rand() % Size) / (Size));
}
std::cout << endl;
}
std::cout << Lattice[Size][Size];
system("pause");
return 0;
}
This is because you haven't successfully built your application so it doesn't exist.
(The actual error message is "The system cannot find the file specified".)
There are several compilation errors:
cin << Size; should be cin >> Size;, and the same for the other input line.
(This is easier to spot if you write on separate lines.)
int rand() should be just rand().
And variable-length arrays are not standard C++.
There are also a couple of logical errors.
Since rand() % Size is less than Size, (rand() % Size) / Size will always be zero.
(This is an integer division.)
Use Lattice[i][j] = (rand() % Size) / static_cast<float>(Size); instead.
Also, I suspect you think that std::cout << Lattice[Size][Size]; will print the entire array.
It won't; it indexes outside of the array in order to access one float and is undefined.
You need to write a loop.

Finding the closest number of array to another given number

I have this program to write that I have a array of 11 numbers entered from me. Then I need to find the avarage sum of those numbers, and then im asked to find the closest number of this array to the avarage sum, and then the most distant element of the array to the avarage sum again. SO far I manage to write a program to create this array and find the avarage sum. I asssume there is something to do with abs function of cmath libary , but so far I only fail to make it.
#include <iostream>
using namespace std;
int main() {
unsigned const int size = 11;
float number[size];
for (unsigned i = 0; i<size; i++) {
cout << "Please enter value for number "
<< i + 1 << ":";
cin >> number[i];
}
for (unsigned i = 0; i<size; i++) {
cout << "Number " << i + 1 << " is : "
<< number[i] << endl;
}
unsigned int sum = 0;
for (unsigned i = 0; i<size; i++) {
sum += number[i];
}
What is the problem? You are not asking a question, just making a statement... It does seem that you have not posted the whole code..
In c++ usually to use "abs" you should use fabs from the "math.h" library!
You will be okay with the compare operators.
Just traverse your array in a loop and calculate the difference between your compare value and the current value on your array. Initiate a temporary variable that keeps the array entry that created the smallest difference.
Every time a difference that is smaller than the current one comes up replace the value in your temporary variable.
So you replace under the following condition: If |number[i] - average_value| < |tmp_closest_val -average_val| Then tmp_closest_val = number[i] EndIf.
I hope you get the concept from that rough draft.

Sequences of random numbers output by program do not match with actual rand() output on Linux (works correctly on Windows)

Hopefully I'm allowed to ask this again now that my closed question got automatically deleted?
So, this is what I'm trying to do:
The program checks sequences of numbers output by rand() % 10 for certain strings of numbers. In this case the strings 444 and 555. So, on Windows, the first sequence that the program finds which contain those strings (looking at only the first 10 numbers), is the sequence output by seed 61163. The sequence is 3355444555.
Now, just to make sure, I check what rand() % 10 actually outputs with that seed with a simple program (both programs shown below), which is 3355444555. Very much expected.
So far everything makes sense.
On Linux however, the output of the program does not match with what rand() actually outputs. So for example, the first sequence that the program finds containing strings 444 and 555 in the first 10 numbers, is the sequence output by seed 154950. The sequence is 4555232444.
Still everything makes sense (rand() has different implementations on Windows/Linux so it makes sense that the first found sequence is completely different than on Windows).
However, and this is the problem: When checking what rand() % 10 actually outputs with that seed, unlike on Windows, the sequences do not match. The sequence that seed 154950 outputs is actually 1778785265. (tested with the same simple program).
And that is my problem. As mentioned before the really weird part is that the code works on Windows, and I'm not sure how anything Linux-specific could screw this up.
The code for the program:
#include <iostream>
#include <sstream>
#include <cstdlib>
using namespace std;
int main()
{
int result;
string text;
int minSeed;
int maxSeed;
string temp;
cout << "Seed Seeker. Checks a range of random seeds for specific strings.\n";
cout << "Random Seed: lowest value: ";
getline(cin, temp);
minSeed = atoi(temp.c_str());
cout << "Random Seed: highest value: ";
getline(cin, temp);
maxSeed = atoi(temp.c_str());
cout << "Generate how many random numbers / seed? ";
getline(cin, temp);
int rndRange = atoi(temp.c_str());
string lookForThisA="444";
string lookForThisB="555";
for (int j = minSeed; j <= maxSeed; ++j)
{
text = "";
for (int i = 0; i < rndRange; ++i){
result = rand() % 10;
text += static_cast<ostringstream*>(&(ostringstream() << result))->str();
}
if (text.find(lookForThisA) != std::string::npos) {
if (text.find(lookForThisB) != std::string::npos) {
std::cout << "\n\n\nString found!!!!\n\n";
cout << text << "\n\nSeed: " << j << " ";
}
}
}
}
Program used to check rand() output:
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
srand(154950);
cout << rand() % 10;
cout << rand() % 10;
cout << rand() % 10;
cout << rand() % 10;
cout << rand() % 10;
cout << rand() % 10;
cout << rand() % 10;
cout << rand() % 10;
cout << rand() % 10;
cout << rand() % 10;
}
Make sure you seed the RNG every loop iteration:
for (int j = minSeed; j <= maxSeed; ++j)
{
srand(j); // <----- without that the RNG is not re-seeded
text = "";
As for Windows vs. Linux my guess is that on Windows (I assume Debug build) the srand was called for you by CRT and the 61163 is not a seed in this case but just a number of times the 10-digit loop iterated before getting to your sequence ;-)